2011-11-06 33 views
-1

因此,这已经让我烦扰了很长一段时间。一旦我使用相同的代码将侦听器添加到另一个元素,事件侦听器似乎就消失了。

我有一个JavaScript构造函数,去不服这样的:

function TimeBlock(c, local_count){ 
    /* creates a timeblock */ 
    . 
    . 
    . 
    _getel(this.id).addEventListener('mouseover', this.displayPopup) 
    _getel(this.id).addEventListener('mouseout', this.killPopup) 
} 

,基本上它创建一个对象TimeBlock并分配给它的两个事件处理程序,这是在TimeBlock.prototype定义像这样:

TimeBlock.prototype = { 
    . 
    . 
    . 
    block = getTimeBlock(e.target.id) 
    //do something 
    }, 

    killPopup: function(e){ 
    // //do something else 
    } 
} 

它的工作原理。我打电话new Timeblock (some_parameters),我得到了我的时间段,它将元素创建到html(它是一个div)并将侦听器分配给它。我测试它,它工作正常。但是一旦我再次调用它,我就会创建一个新的TimeBlock元素,并有工作监听器,但前一个元素停止工作。这就像将这些侦听器分配到新元素上会取消应该在前一个元素上的侦听器。

什么是更奇怪的是,我已经通过JavaScript控制台手动分配这些监听器,它在那里工作得很好。我正在使用Firefox 7.0.1和Firebug进行这些测试。

非常感谢

+0

边注:'在IE不支持addEventListener'直到IE9,因此,除非您可以忽略IE6,IE7和IE8用户,如果它存在,则需要使用'addEventListener';如果不存在,则需要使用'attachEvent'(微软的原始版本)。这不是你遇到的问题(这是* next *问题,你会有;-))。或者,当然,使用任何好的JavaScript库[jQuery](http://jquery.com),[Prototype](http://prototypejs.org),[YUI](http://developer.yahoo.com/ yui /)或[其他任何一个](http://en.wikipedia.org/wiki/List_of_JavaScript_libraries)喜欢为你平滑这些差异。 –

+0

我不认为'这'是这里的问题。我尝试将这些函数设置为实现相同(有缺陷)结果的全局函数。 – user986730

+0

'@ user':不知道还有什么可以告诉你的,从根本上把事情搞好并不会导致你描述的行为。我用另一个想法更新了我的答案,并用一个演示我所描述技术的实例来更新我的答案。 –

回答

0

此代码是可疑的:

_getel(this.id).addEventListener('mouseover', this.displayPopup) 

...因为虽然你挂接函数为事件处理,你没有做任何事情来保存什么this意味着在处理程序内。所以当处理程序被调用时,this而不是与上面代码中的相同。我怀疑this意味着什么导致了当您尝试使用多个TimeBlock实例执行此操作时看到的效果。

有不同的方法,以确保您的函数调用正确的this值,其中一个看起来是这样的:

function TimeBlock(c, local_count){ 
    /* creates a timeblock */ 
    . 
    . 
    . 
    var self = this; 
    _getel(this.id).addEventListener('mouseover', function(event) { 
     self.displayPopup(event); 
    }); 
    _getel(this.id).addEventListener('mouseout', function(event) { 
     self.killPopup(event); 
    }); 
} 

更多阅读:

The只有想到的其他东西是mouseovermouseout冒泡到父元素,如果你不小心可能会造成混淆。因此,举例来说,如果您有:

<div>Foo <span>bar</span></div> 

...你看有关divmouseovermouseout,你会看到mouseout当从span(“酒吧”),将鼠标移动到div( “foo”),如果你不期待它会令人惊讶。


下面是一个例子展示两个独立实例钩到独立的要素按照上述(live copy):

window.onload = function() { 

    new TimeBlock("firstElement"); 
    new TimeBlock("secondElement"); 

    function _getel(id) { 
     return document.getElementById(id); 
    } 

    function TimeBlock(id){ 
     var self = this; 
     this.id = id; 
     this.counter = 0; 
     _getel(this.id).addEventListener('mouseover', function(event) { 
      self.displayPopup(event, this); 
     }); 
     _getel(this.id).addEventListener('mouseout', function(event) { 
      self.killPopup(event, this); 
     }); 
    } 

    TimeBlock.prototype.displayPopup = function(event, element) { 
     ++this.counter; 
     element.innerHTML = "Display, counter = " + this.counter; 
    }; 

    TimeBlock.prototype.killPopup = function(event, element) { 
     element.innerHTML = "Remove, counter = " + this.counter; 
    }; 

}; 
+0

仍然是不正确的。由于从控制台添加监听器工作正常,我试着正确地复制我在控制台中输入的内容。我创建了一个如下所示的字符串: ''='_ getel(\“”+ this.id +“\”) '确定它是正确的,然后用'eval()'运行它。相同的行为:创建与工作侦听器的第一个对象,听众消失,因为我创建第二个对象。听众在最后创建的对象上工作。 – user986730

+0

@ user986730:**显示您的非工作代码**,我们会指出为什么它不起作用。你所展示的代码在很大程度上没有问题(除了上面列出的问题外,你还有'='你应该在一个地方有':')。 –

相关问题