Mouseout会持续发射

时间:2014-07-02 03:37:56

标签: javascript

所以我有一个分配鼠标悬停的功能,这会将一个悬停工具提示div和一个mouseout事件添加到触发它的div中,这样我就可以删除工具提示。

问题是mouseout事件触发但是当我将鼠标移动到div之外的任何地方时会一直触发,因此它会为鼠标的每个像素移动触发许多次数。

这是设置:

function ToolTip(data)
{
    var div           =  createDiv();
        div.className = 'ToolTip';
        div.innerHTML = 'This is a tooltip!';

    addChild(div,document.body); // appends to given element
    this.addEventListener('mouseout',function(){removeToolTip(div);},false);
}
function removeToolTip(el)
{
    console.log('test');
    this.removeEventListener('mouseout',removeToolTip,false);
    removeDiv(el);  //removes perfectly fine
}


for(var i=0;i<data.length;i++)
{
 var div = document.getElementById('id'+i);
    (function(i){
        div.addEventListener("mouseover",function(){ToolTip(data[i]);},false);
    })(i);              
}

我不明白为什么mouseout会继续触发,我在我的控制台日志中得到test所以它应该删除事件监听器。我哪里出错?

1 个答案:

答案 0 :(得分:1)

您的事件处理逻辑非常混乱。

首先,您要为一系列div中的每一个添加一个鼠标悬停事件处理程序。

然后,每次触发鼠标悬停事件(可能多次)时,您调用的ToolTip()会在this上添加一个鼠标输出事件,该事件似乎是window个对象因为ToolTip()只是一个简单的函数调用,所以this将是全局对象或undefined(在严格模式下)。

然后,在removeToolTip(),您正试图致电removeEventListener('mouseout', ...),但这不会奏效,因为您传递的功能不同于addEventListener()用过的。 removeEventListener()要求您传递与传递给addEventListener()的完全相同的功能,否则它将无法执行任何操作。因此,由于您正在传递不同的函数,因此不会删除任何内容,并且会在窗口对象上生成mouseout事件和所有内容。

在结构上,您需要修复:

  1. 确保您在正确的对象上安装事件处理程序。你职能中的this并不是你想要的。我建议你停止在这些函数中使用this,并将你想要操作的对象作为这些函数的参数传递。

  2. 将实际的命名函数(不是匿名函数)传递给addEventListener(),以便以后可以将其与removeEventListener()一起使用。

  3. 当您致电removeEventListener()时,您必须传递与addEventListener()一起使用的完全相同的命名功能参考。

  4. 请确保您也尝试在正确的对象上拨打removeEventListener()

  5. 有关如何在函数调用中设置this的详细信息,请参阅this prior answer中的五个编号点。