jQuery Click event triggers more times on every window resize

javascript, jquery, responsive-design

Solution

The `resize` event is triggered multiple times during resizing, and each time you're binding a new click handler. My suggestion: bind only once, from outside the resize handler, and set a flag while resizing to let the click handler know if it should do something or not.

Then you won't even need to defer the handling of `resize` with `setTimeout` as you're doing.

DEMO

jQuery(function($){

    var i = 1;

    // flag to allow clicking
    var clickAllowed = true;

    // click function
    $('.sub-toggle').click(function(){
        if(clickAllowed) {
            alert('click');

            if($(this).hasClass('active')){
                alert('active');
                $(this).removeClass('active');
            } else {
                $(this).addClass('active');
            }
        }
    }); 

    // check if browser size is compatible with click event
    onResize = function() {

        //if browser size is ok, do the click function
        if($(window).width() <= 480){
            clickAllowed = true;
        }
        else{
            // if browser size is greater than expected, disallow clicking
            clickAllowed = false;

        }

        // just checking how many times the resize function is triggered 
        console.log('resize: '+ i);
        i++;

    }

    $(document).ready(onResize);

    var timer;
    $(window).bind('resize', onResize);
});

Problem

People! This is the first time I come here to ask something, so far, always when I had a problem, I could find a good answer here. So, in first place, thanks for this amazing community! Now let's go to the problem: I'm doing a responsive menu that check the window.resize event and, when it fits the minimum browser width, a click function for a button is allowed. If the browser width is greater, then the click function is unbound. I need to do this because the same element that is the button on the mobile version, is a visual element on the desktop version. The problem is that, with the code that I have now, when the page is loaded, the click function works fine. But, if I resize the browser and click on the element again, it triggers more than once the state, sometimes leaving the impression that the function isn't triggered. And, if I resize the browser again, it triggers the click function more than the last time I clicked. Really annoying. To help understand what is happening, I've made a simple example. Here's is the simple code (just to check the click function issue): HTML: ``` <ul> <li><span class="sub-toggle">Testing 01</span></li> <li><span class="sub-toggle">Testing 02</span></li> <li><span class="sub-toggle">Testing 03</span></li> </ul> ``` CSS: ``` .sub-toggle{ display:block; padding: 20px; } .sub-toggle.active{ background-color: #ffcc00; color: #fff; } ``` Javascript (jQuery): ``` jQuery(function($){ var i = 1; // check if browser size is compatible with click event onResize = function() { // if browser size is ok, do the click function if($(window).width() <= 480){ // click function $('.sub-toggle').click(function(){ alert('click'); if($(this).hasClass('active')){ alert('active'); $(this).removeClass('active'); } else { $(this).addClass('active'); } }); } else{ // if browser size is greater than expected, unbind the click function $('.sub-toggle').removeClass('active').unbind('click'); } // just checking how many times the resize function is triggered console.log('resize: '+ i); i++; } $(document).ready(onResize); var timer; $(window).bind('resize', function(){ timer && clearTimeout(timer); timer = setTimeout(onResize, 500); }); }); ``` (Edited to remove some unnecessary code) If you want to see it in action, I've made a Fiddle (try resize the output frame to see it working): http://jsfiddle.net/C7ppv/1/ Maybe I've missing something really stupid, since I don't have a huge knowledge in JavaScript. But what I want to do is just trigger the click event once, even if multiple resizes. I hope I could explain well my problem. I've searched and didn't found a solution for this issue (or maybe I just didn't know really well what to look for). Any help would be appreciated!

Original source