简体   繁体   中英

Why is this jQuery function failing when called on multiple times?

I've created a dialog box and a jQuery function to open / close this. My problem is that after I click 'open' button a second time, something happens and it will not remove the show class.

I'm guessing it's because after being called the first time, "it's still there" when I call it a second time. I have me JS fiddle here to test .

What am I doing wrong for this to not work?

// JS code
$.fn.sl_dialog = function(params){
    var self = this;

    self.after('<div class="dialog-background"></div>')
    $('.dialog').toggleClass('show');

    $('.dialog .close, .dialog .button.no').on('click', function(){
        $('.dialog-background').remove();
        $('.dialog').toggleClass('show');
    });

    return false;
}


$('.clickme').on('click', function(){
    $('.dialog').sl_dialog();
});

Move the onclick to outside the function

$.fn.sl_dialog = function(params){
    var self = this;
    self.after('<div class="dialog-background"></div>')
    $('.dialog').toggleClass('show');
    return false;
}
$('.dialog .close, .dialog .button.no').on('click', function(){
    $('.dialog-background').remove();
    $('.dialog').toggleClass('show');
});

Here is the updated Fiddle

The problem is that your initialization function ( sl_dialog ) is binding the close handler every time the dialog is initialized, so when you re-open the dialog the event is bound once again.

When closing the dialog the handler is running twice and the toggleClass('show') is reverting itself.

Either unbind the handler before applying it:

$('.dialog .close, .dialog .button.no').off().on('click', function(){ ...

Or use one() :

$('.dialog .close, .dialog .button.no').one('click', function(){ ...

See one() and off() documentation.

I was able to fix the issue by changing the toggleClass to specify addClass removeClass

http://jsfiddle.net/b877sc20/6/

I am not 100% as to why this matters, but it seems to

$.fn.sl_dialog = function(params){
    var self = this;

    self.after('<div class="dialog-background"></div>')
    $('.dialog').addClass('show');

    $('.dialog .close, .dialog .button.no').on('click', function(){
        $('.dialog-background').remove();
        $('.dialog').removeClass('show');
    });

    return false;
}


$('.clickme').on('click', function(){
    $('.dialog').sl_dialog();
});

The problem is that you're registering the click event multiple times as already other people said.

Try adding a flag to detect if you are calling the method for first time so you avoid adding the same event handler more than once.

$.fn.sl_dialog = function(params){
    var self = this;

    self.after('<div class="dialog-background"></div>')
    $('.dialog').toggleClass('show');

    if (!self.data('initialized')) {
        $('.dialog .close, .dialog .button.no').on('click', function(){
            $('.dialog-background').remove();
            $('.dialog').toggleClass('show');
        });

        // Add the flag to avoid registering again
        self.data('initialized', true); 
    }

    return false;
}

DEMO

If you need all code in function area you have to unbind click event as it is bind every time you click on. Try this

http://jsfiddle.net/ycsqequf/

$.fn.sl_dialog = function(params){
var self = this;

self.after('<div class="dialog-background"></div>')
$('.dialog').toggleClass('show');

 $( ".dialog .close, .dialog .button.no" ).off( "click" );
$('.dialog .close, .dialog .button.no').on('click', function(){
    $('.dialog-background').remove();
    $('.dialog').toggleClass('show');
})

return false;
}


$('.clickme').on('click', function(){
$('.dialog').sl_dialog();
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM