在循环内部应用mouseover事件侦听器

Applying a mouseover event listener inside of a loop

本文关键字:事件 侦听器 mouseover 应用 循环 内部      更新时间:2023-09-26

我有一个按钮(<a class="gmButton"></a>)和一个<span id="gmToolTip"></span>,我希望span在鼠标悬停相关链接时显示某些文本。

要显示的文本是一个名为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);
});

当一个接一个地应用到链接时,代码似乎可以按预期执行。在这样的循环中应用时,它不起作用。我搞砸了什么?

小提琴在这儿:http://jsfiddle.net/d5tpqt5h/1/

问题是,在遍历完所有元素之后,事件侦听器函数就会被触发。这意味着当调用它们时,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()方法将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);
  });
}

gmTooltip.textContent = null;更改为gmToolTip.textContent = null;

gmTooltip到gmTooltip

希望它能有所帮助!

尝试使用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);
}

演示