Mootools - 如何销毁类实例

时间:2010-06-06 01:04:42

标签: javascript class mootools

我要做的是创建一个可以快速附加到链接的类,它将获取并显示链接到的文档的缩略图预览。现在,我在这里专注于易用性和可移植性,我想简单地将鼠标悬停事件添加到这样的链接:

<a href="some-document.pdf" onmouseover="new TestClass(this)">Testing</a>

我意识到还有其他方法可以解决我的问题,我可能最终必须这样做,但是现在我的目标是按上述方式实现。我不想手动向每个链接添加一个mouseout事件,我不希望代码在类中的任何地方(以及创建类实例的mouseover事件)。

代码:

TestClass = new Class({
    initialize: function(anchor) {
        this.anchor = $(anchor);
        if(!this.anchor) return;

        if(!window.zzz) window.zzz = 0;
        this.id = ++window.zzz;

        this.anchor.addEvent('mouseout', function() {
            // i need to get a reference to this function
            this.hide();
        }.bind(this));

        this.show();

    },
    show: function() {
        // TODO: cool web 2.0 stuff here!
    },
    hide: function() {
        alert(this.id);

        //this.removeEvent('mouseout', ?);  // need reference to the function to remove

        /*** this works, but what if there are unrelated mouseout events? and the class instance still exists! ***/
        //this.anchor.removeEvents('mouseout');

        //delete(this);  // does not work !
        //this = null; // invalid assignment!
        //this = undefined; // invalid assignment!

    }
});

以上代码目前发生了什么:

  • 第一次出局:提醒1
  • 第二次出局:提醒1,2
  • 第3次出局:提醒1,2,3

期望的行为:

  • 第一次出局:提醒1
  • 第二次出局:提醒2
  • 第3次出现:提醒3

问题是,每次我将鼠标悬停在链接上时,我都会创建一个新的类实例,并为该实例附加一个新的mouseout事件。类实例也无限期地保留在内存中。

在mouseout上我需要删除mouseout事件并销毁类实例,所以在随后的鼠标移动中我们开始新鲜。

我可以为此创建一个辅助函数,以确保只为每个链接创建一次类,如下所示:

function TestClassHelper(anchor) {
    anchor = $(anchor);
    if(!anchor) return;

    if(!anchor.retrieve('TestClass')) anchor.store('TestClass', new TestClass(anchor));
    anchor.retrieve('TestClass').show();
}

<a href="some-document.pdf" onmouseover="TestClassHelper(this)">Testing</a>

如果必须的话,我最终可能会以这种方式实现它,但我很好奇如何修复其他方法。

1 个答案:

答案 0 :(得分:3)

这看起来比它应该复杂得多。但是如果你想解决这个问题,你需要在某处保存对绑定函数的引用,然后将其传递给removeEvent

例如:

// inside initialize
this.boundHandler = function() {
    this.hide();
}.bind(this)
this.anchor.addEvent('mouseout', this.boundHandler);

// inside hide    
this.removeEvent('mouseout', this.boundHandler);

有关此问题的示例,请参阅removeEvent docs

出于性能原因,我不建议在此处进行事件委托。最好的方法是在代码中而不是内联中附加处理程序,并且只执行一次,因此每次用户鼠标悬停时都不会创建不必要的对象。