I have a web app which loads a set of data with ajax, that data launches a lightbox, when the lightbox closes I need to refresh the original data by recalling the initial ajax. I am hitting some issues keeping the javascript in scope.
index.php has some ajax in it to draw the list of child pages:
<!-- Container for the content -->
<div id="pageListContainer" data-category-id="1"></div>
<script>
// Re-usable function to draw the pages
function drawPageList() {
var container = '#pageListContainer';
var categoryId = $(container).data('categoryId');
$.post('webservice.php', {action: 'drawPageList', categoryId: categoryId}, function(data) {
$(container).removeClass('loading').html(data);
});
}
// Now draw the pages
drawPageList();
// Function to open the page links as an iFrame in a lightbox
$('#pageList a').click(function(event) {
event.preventDefault();
$.fancybox({
type : 'iframe',
padding : 0,
autoSize: false,
width: 440,
height: 440,
href: this.href + "&lightbox=true",
});
});
</script>
webservice.php will return something like this:
<ul id="pageList">
<li><a href="page.php?pageId=1">Page One</a></li>
<li><a href="page.php?pageId=2">Page Two</a></li>
<ul>
The above fails because the lightbox open function targets "#pageList a" and that part of the DOM is loaded via ajax. To solve this I can add the $('#pageList a').click() function to the ajax result from webservice.php, but then I'm segmenting my JS into multiple places and I get other scope issues. Is there a best practice for global scope of JS functions like this?
Use event delegation. This lets you attach the event handler to a parent element that remains in the DOM instead of being dynamically loaded. For example:
$('#pageListContainer').on( 'click', '#pageList a', function( event ) {
// ...
});
Instead of attempting to attach an event handler to the '#pagelist a'
elements, this attaches it to the '#pageListContainer'
parent element.