I thought I had fixed this on Friday through a type correction, but I did not 🙁
I have been beating my head trying to find a solution to this problem (if there is one to be had). Maybe I’m not searching for the right thing, but I just can’t find a solution to this one…
The Setup:
$.myPlugin = function(element, options){
this.myElement = $(element);
this.myElement.data('rotator', '');
this.myElement.data('settings', $.extend({}, $.myPlugin.defaultOptions, options));
this.mainFunction(this.myElement);
};
$.myPlugin.defaultOptions = { // yadda yadda };
$.myPlugin.prototype = {
mainFunction : function(myself){
// establish initial parameters
var TEST = Math.rand();
// do a bunch of stuff
$(myButton).live('click', function(){
alert(TEST) //<---FOR TESTING PURPOSES
// do other things
myself.data('rotator', setTimeout(function(){
// click button after x period
myButton.click();
}, x ));
});
},
destroy : function(){
myself = $(this);
myself.myElement.removeData('settings');
clearTimeout(myself.data('rotator'));
}
};
$.fn.myPlugin = function(options) {
// parse options
this.each(function(){
var instance = $(this).data('myPlugin');
// blah blah blah ... on create
$(this).data('myPlugin', new $.myPlugin(this, args));
// blah blah blah ... on destroy
instance['destroy'].apply(this);
$(this).data('ddGallery', null);
};
return this;
};
The Desired Function:
In my logic, I want to create an object on an element. The plugin then stores the contents of the element in a variable, and puts new content in it. There is an auto-timed event that is invoked on click, with a .live() click listener; the click event resets the timer resulting in a loop (as opposed to using setInterval). On destroy, I replace the stored original html contents and want to kill the object. So far, this all works. I want to then be able to recreate the object on the element (perhaps passing in different settings).
This is where it all goes wrong:
When I recreate the object on the same element after destruction, the original timer continues to run. I can’t get rid of the stinkin’ timer, and I’m about to rip my hair out!
To test, I set a random number on initialization, and alert that number on click. Initially, I might get an alert of, for example, “0.1234”. I can then destroy the object (I’m just using a listener on a form button to create and destroy). The element will return to it’s initial state, and happily sit indefinitely. However, as soon as I run the plugin on the element again, the original “0.12345” alert pops up immediately with no delay (and all animations fire). That is followed by another new popup, e.g., “0.5678”. Now BOTH timers continue to fire on the element, wreaking havoc.
What am I missing?
You aren’t unbinding the original click event on the button in your destroy method. You need to add a call like:
in your destroy method. The reason you are seeing the original random number alerted on the future click is because you bound a closure to the click event the first time through. You kill the timer but don’t unbind the click handler.
The next time you click the button you bind a new click handler; now you have TWO click handlers, each of which is a closure that remembers the random number that was generated at the time it was created. Now a single timer fires repeatedly clicking the element and each time it clicks it triggers both click handlers.