How to destroy a jQuery.fn whenever it is called?

4

I built a plugin using jQuery.fn.algumaCoisa = function(options, callback){}; , but when I call multiple times on the same element, it multiplies the behavior instead of overlapping. Is there any way I always call this function to reset the effect on the element?

When calling on the same element it should reset the behavior, but the internal buttons are having multiplied effect, in short, they are not losing the effects previously assigned.

$('div').algumaCoisa(); // usario clica em um botão e chama
$('div').algumaCoisa(); // usario clica em um botão e chama
$('div').algumaCoisa(); // usario clica em um botão e chama
    
asked by anonymous 31.08.2015 / 23:39

3 answers

2

Your problem occurs because events are set cumulatively, so let's figure out a little bit about the way you've implemented it. I'll show you two examples with the event of .click() and .on() which are two jQuery event handlers available in 1.7+ versions.

Using .click() :

jQuery.fn.algumaCoisa = function(){ 

    //ele remove todos os eventos de click antes de setar
    $(this).unbind('click');

    //seta seu evento
    $(this).click(function() {
        alert("teste1");
    });    
}

Using .on() :

jQuery.fn.algumaCoisa = function(){ 

    //ele remove todos os eventos de click antes de setar
    $(this).unbind('click');

    //seta seu evento
    $(this).on('click', function() {
        alert("teste1");
    });    
}

Follow jsfiddle , if you're using any different way to set the event, just talk in the comments!

    
01.09.2015 / 02:51
1

The jQuery.fn function does not assign anything, it just passes the selected nodes to your custom method. Who defines if it will add repeatedly and you.

In case you can use attr() to detect if the node has already received the attribute (if you will only use it for nodes), I recommend that you also check that the selected item is really a node, since $(...) can receive window and document as well.

function isDOM(el) {
   return el && el instanceof HTMLElement;
}

jQuery.fn.foo = function() {
    this.each(function() {
       if (isDOM(this) && $(this).attr("data-foo") !== "true") {
           $(this).attr("data-foo", "true");

           //Algo aqui
       }
    });
};

In this way you can make several different selectors and it will detect if the html element already has the expected effect.

If what you want and remove the effect on elements that already have it, you can do so:

function aplicaEfeito(el) {
    //Aqui aplica o efeito
}

function removeEfeito(el) {
    //Aqui remove o efeito
}

function isDOM(el) {
   return el && el instanceof HTMLElement;
}

jQuery.fn.foo = function() {
    this.each(function() {
       if (isDOM(this)) {
           if ($(this).attr("data-foo") !== "true") {
               $(this).attr("data-foo", "true");
                aplicaEfeito($(this));//Aplica o efeito
           } else {
                removeEfeito($(this));//Primeiro remove o efeito
                aplicaEfeito($(this));//Aplica o efeito novamente
           }
       }
    });
};
    
01.09.2015 / 04:15
0

Do this:

delete $.fn.nomedoplugin;

This does not affect plugin instances already initialized.

    
01.09.2015 / 00:02