Javascript、原型对象、jQuery和定时器

3

我原以为上周五通过修改类型已经修复了这个问题,但事实并非如此 :(

我一直在煞费苦心地寻找解决这个问题的方法(如果有的话)。也许我没有搜索到正确的内容,但我就是找不到解决这个问题的方法...

背景设置:

$.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;
};

所需功能:

在我的逻辑中,我想在一个元素上创建一个对象。然后,插件会将元素的内容存储在一个变量中,并放置新内容。有一个自动定时事件,在点击时被调用,具有.live()点击监听器;点击事件重置计时器,导致循环(而不是使用setInterval)。在销毁时,我替换存储的原始html内容并希望杀死对象。到目前为止,这一切都很好用。我想能够重新在元素上创建对象(也许传入不同的设置)。

这就是一切的问题所在:

当我在销毁后在同一个元素上重新创建对象时,原始计时器仍然在运行。我无法摆脱该可恶的计时器,我快要抓狂了!

为了测试,我在初始化时设置了一个随机数,并在单击时警报该数字。最初,我可能会收到例如“0.1234”的警报。然后,我可以销毁对象(我只是在表单按钮上使用监听器来创建和销毁)。元素将返回其初始状态,并愉快地坐在那里无限期地。然而,一旦我再次对元素运行插件,原始的“0.12345”弹出警报立即出现,没有延迟(并且所有动画都会触发)。然后是另一个新弹出窗口,例如“0.5678”。现在,BOTH计时器都继续在元素上触发,制造混乱。

我错过了什么?


那是您真正的代码吗?clearTimeout(myself.data('rotator');缺少一个闭括号。 - James M
不是实际代码,只是为了提供概述 - ValZho
是的...又出了点小错,已经修复好了...应该用$.extend()。 - ValZho
2个回答

3

您的destroy方法中没有解除按钮上原有的点击事件。您需要添加以下代码:


``` $(button).off('click'); ```
   myself.die('click');

在你的销毁方法中。之所以在下一次单击时看到原始的随机数弹出,是因为第一次通过闭包绑定了单击事件。你结束了计时器,但没有解除单击处理程序。
下次单击按钮时,您将绑定一个新的单击处理程序;现在您有两个单击处理程序,每个处理程序都是创建时记住生成的随机数的闭包。现在一个计时器重复触发单击元素,并且每次单击都会触发两个单击处理程序。

0

尝试不使用jQuery的data函数,我有一种感觉你代码中创建新的jQuery对象会影响你引用计时器的能力。请尝试

 this.rotator = setTimeout(...

对比

 $(this).data('rotator', setTimeout(...

清除的样子应该是这样的:

clearTimeout(this.rotator);

我尝试了两种方式,但没有任何区别。如果我在destroy函数内部警报rotator变量,则会返回id,但它只是无法清除。...嗯...也许如果我创建一个“setMyTimer”函数并将其放在原型之外?(或者我是否误解了继承?我对OOP还相当新) - ValZho

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接