在循环内应用鼠标悬停事件侦听器
Applying a mouseover event listener inside of a loop
我有一个按钮 (<a class="gmButton"></a>
) 和一个 <span id="gmToolTip"></span>
,我希望 span
在相关 link 鼠标悬停时显示特定文本。
要显示的文本是一个名为 toolTips
的字符串数组。
gmButtons[i].addEventListener("mouseover", function(){
clearTimeout(t);
t = setTimeout(function() {
gmToolTip.textContent = toolTips[i];
}, 500);
});
gmButtons[i].addEventListener("mouseout", function(){
gmToolTip.textContent = null;
clearTimeout(t);
});
当一个接一个地应用于 link 时,代码似乎按预期执行。在这样的循环中应用时它不起作用。我搞砸了什么?
这是 fiddle:http://jsfiddle.net/d5tpqt5h/1/
将gmTooltip.textContent = null;
更改为gmToolTip.textContent = null;
gmTooltip to gmToolTip
希望对您有所帮助!
问题是事件侦听器函数是在您循环遍历所有元素之后触发的。这意味着当调用它们时,i
等于 9
(并且 toolTips[9]
未定义,因为数组中最后一个元素的索引比其 length
小一)。
一种选择是将逻辑包装在 IIFE 中,以便捕获 i
的当前值:
for (var i = 0; i < gmButtons.length; i++) {
(function(i) {
gmButtons[i].addEventListener("mouseover", function() {
clearTimeout(t);
t = setTimeout(function() {
gmToolTip.textContent = toolTips[i];
}, 500);
});
gmButtons[i].addEventListener("mouseout", function() {
gmToolTip.textContent = null;
clearTimeout(t);
});
})(i);
}
或者,您也可以利用 .bind()
method 将 i
的当前值传递给函数:
for (var i = 0; i < gmButtons.length; i++) {
gmButtons[i].addEventListener("mouseover", function(i) {
clearTimeout(t);
t = setTimeout(function() {
gmToolTip.textContent = toolTips[i];
}, 500);
}.bind(this, i));
gmButtons[i].addEventListener("mouseout", function() {
gmToolTip.textContent = null;
clearTimeout(t);
});
}
尝试使用 innerHTML 和闭包:
for (var i = 0; i < gmButtons.length; i++){
(function(i) {
gmButtons[i].addEventListener("mouseover", function(){
clearTimeout(t);
t = setTimeout(function() {
gmToolTip.innerHTML = toolTips[i];
}, 500);
});
gmButtons[i].addEventListener("mouseout", function(){
gmTooltip.innerHTML = null;
clearTimeout(t);
});
})(i);
}
我有一个按钮 (<a class="gmButton"></a>
) 和一个 <span id="gmToolTip"></span>
,我希望 span
在相关 link 鼠标悬停时显示特定文本。
要显示的文本是一个名为 toolTips
的字符串数组。
gmButtons[i].addEventListener("mouseover", function(){
clearTimeout(t);
t = setTimeout(function() {
gmToolTip.textContent = toolTips[i];
}, 500);
});
gmButtons[i].addEventListener("mouseout", function(){
gmToolTip.textContent = null;
clearTimeout(t);
});
当一个接一个地应用于 link 时,代码似乎按预期执行。在这样的循环中应用时它不起作用。我搞砸了什么?
这是 fiddle:http://jsfiddle.net/d5tpqt5h/1/
将gmTooltip.textContent = null;
更改为gmToolTip.textContent = null;
gmTooltip to gmToolTip
希望对您有所帮助!
问题是事件侦听器函数是在您循环遍历所有元素之后触发的。这意味着当调用它们时,i
等于 9
(并且 toolTips[9]
未定义,因为数组中最后一个元素的索引比其 length
小一)。
一种选择是将逻辑包装在 IIFE 中,以便捕获 i
的当前值:
for (var i = 0; i < gmButtons.length; i++) {
(function(i) {
gmButtons[i].addEventListener("mouseover", function() {
clearTimeout(t);
t = setTimeout(function() {
gmToolTip.textContent = toolTips[i];
}, 500);
});
gmButtons[i].addEventListener("mouseout", function() {
gmToolTip.textContent = null;
clearTimeout(t);
});
})(i);
}
或者,您也可以利用 .bind()
method 将 i
的当前值传递给函数:
for (var i = 0; i < gmButtons.length; i++) {
gmButtons[i].addEventListener("mouseover", function(i) {
clearTimeout(t);
t = setTimeout(function() {
gmToolTip.textContent = toolTips[i];
}, 500);
}.bind(this, i));
gmButtons[i].addEventListener("mouseout", function() {
gmToolTip.textContent = null;
clearTimeout(t);
});
}
尝试使用 innerHTML 和闭包:
for (var i = 0; i < gmButtons.length; i++){
(function(i) {
gmButtons[i].addEventListener("mouseover", function(){
clearTimeout(t);
t = setTimeout(function() {
gmToolTip.innerHTML = toolTips[i];
}, 500);
});
gmButtons[i].addEventListener("mouseout", function(){
gmTooltip.innerHTML = null;
clearTimeout(t);
});
})(i);
}