所以我有一个分配鼠标悬停的功能,这会将一个悬停工具提示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
所以它应该删除事件监听器。我哪里出错?
答案 0 :(得分:1)
您的事件处理逻辑非常混乱。
首先,您要为一系列div中的每一个添加一个鼠标悬停事件处理程序。
然后,每次触发鼠标悬停事件(可能多次)时,您调用的ToolTip()
会在this
上添加一个鼠标输出事件,该事件似乎是window
个对象因为ToolTip()
只是一个简单的函数调用,所以this
将是全局对象或undefined
(在严格模式下)。
然后,在removeToolTip()
,您正试图致电removeEventListener('mouseout', ...)
,但这不会奏效,因为您传递的功能不同于addEventListener()
用过的。 removeEventListener()
要求您传递与传递给addEventListener()
的完全相同的功能,否则它将无法执行任何操作。因此,由于您正在传递不同的函数,因此不会删除任何内容,并且会在窗口对象上生成mouseout事件和所有内容。
在结构上,您需要修复:
确保您在正确的对象上安装事件处理程序。你职能中的this
并不是你想要的。我建议你停止在这些函数中使用this
,并将你想要操作的对象作为这些函数的参数传递。
将实际的命名函数(不是匿名函数)传递给addEventListener()
,以便以后可以将其与removeEventListener()
一起使用。
当您致电removeEventListener()
时,您必须传递与addEventListener()
一起使用的完全相同的命名功能参考。
请确保您也尝试在正确的对象上拨打removeEventListener()
。
有关如何在函数调用中设置this
的详细信息,请参阅this prior answer中的五个编号点。