Ayan Ayan - 5 months ago 13
jQuery Question

Why is a click handler not registering on page load using Enquire.js?

I am trying to have various effects on different breakpoints.

Primarily what I am trying to do is when a category is clicked from the category list within 720px the category list should fade out and data should be revealed in that place but when the width goes beyond 720px, the category list shouldn't fade out instead reveal the data in another div.

For now am logging responses in console.

PROBLEM

Whenever the page loads in a particular width, click is not performed but once I resize the browser thereon the clicks start registering.

I know the details might not be enough but still..

JS

$(document).ready(function(){
$.ajax({
url: "./assets/listcategory.php",
cache: false,
success: function(response){
$('#content').html(response);
}
});



enquire
.register('screen and (max-width: 720px)', {
match: function() {

console.log('Width less than 720');

jQuery('.category').off('click.catSelect');
jQuery('.category').on('click.catSelect', function() {

var category = $(this).data('categories');
$.when($('.category').fadeOut(500)).done(function(){
//$(this).remove();
});
console.log('click within 720');

}
})
.register('screen and (min-width: 721px)', {
match: function() {

console.log('width greater than 720');

if($('.category').is(':hidden')) {
$.when($('.category').fadeIn(500)).done(function(){
//$(this).remove();
});
}

jQuery('.category').off('click.catSelect');
jQuery('.category').on('click.catSelect', function() {

console.log('Click outside 720');
});

}

})

});

Answer

The reason is that your .category elements have not loaded yet when you call the register method, and so jQuery('.category') will not match any element, and no event handler is bound.

By the time you resize your browser, the content has been loaded, so that then the elements are found, and handlers are bound successfully.

There are several ways to solve this.

One is to move the calls to register into the Ajax success callback, right after you load the html.

Or, you can leave the code where it is, but use event delegation.

jQuery('#content').off('click.catSelect', '.category');
jQuery('#content').on('click.catSelect', '.category', function() { ... });

Note that the on and off calls are now made on the #content selector (could even be document if you wanted to), and that the .category selector is passed as second argument. This means it will work for .category elements that exist now or in the future, which is what you need.