【问题标题】:Applying a mouseover event listener inside of a loop在循环内应用鼠标悬停事件侦听器
【发布时间】:2015-12-05 20:34:34
【问题描述】:

我有一个按钮 (<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/

【问题讨论】:

    标签: javascript mouseover


    【解决方案1】:

    问题是事件监听器函数是在你循环遍历所有元素之后触发的。这意味着当它们被调用时,i 等于 9(并且 toolTips[9] 未定义,因为数组中最后一个元素的索引比它的 length 小一)。

    一种选择是将逻辑包装在IIFE 中,以便捕获i 的当前值:

    Updated Example

    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() methodi 的当前值传递给函数:

    Updated Example

    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);
      });
    }
    

    【讨论】:

    • 这与词法范围有关吗?
    【解决方案2】:

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

    gmTooltip 到 gmToolTip

    希望对你有帮助!

    【讨论】:

    • 啊,谢谢,那太笨拙了。可悲的是,这不是解决方案
    【解决方案3】:

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

    Demo

    【讨论】:

    • innerHTML 不是 XSS 的目标吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-11-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-13
    • 1970-01-01
    相关资源
    最近更新 更多