0

我正在尝试将 onmouseover/out 事件附加到页面上的所有锚标记(想法是在 onmouseover 下添加它并在 onmouseout 上删除它)。

我做了以下代码。它将事件附加到所有锚点,但鼠标悬停在任何锚点上,它始终只为页面中的最后一个锚点添加下划线。

任何想法,可能是什么问题?

window.onload = function () {

    var elArray = document.getElementsByTagName("a");
    if (elArray != null && elArray.length > 0) {
        for (var count = 0; count < elArray.length; count++) {
            var el = elArray[count];
            if (el.addEventListener) {
                el.addEventListener("mouseover", function () {
                    el.style.textDecoration = 'underline'
                }, false);
                el.addEventListener("mouseout", function () {
                    el.style.textDecoration = 'none'
                }, false);
            } else {
                el.attachEvent('onmouseover', function () {
                    el.style.textDecoration = 'underline'
                });
                el.attachEvent('onmouseout', function () {
                    el.style.textDecoration = 'none'
                });
            }

        } //for
    } //if
}; //end of window.onload
4

3 回答 3

2

这是由于范围问题;el不局限于循环的每次迭代for,它的范围是整个函数,所以一旦for循环完成执行,就会el引用最后一个元素。由于el事件处理函数内部是同一个变量,它们只会影响<a>页面上的最后一个元素。

然而,没有必要为此使用 JavaScript,同样的事情使用 CSS 已经有很长一段时间了。以下应该有效:

a {
    text-decoration: none;
}

a:hover {
    text-decoration: underline;
}

如果您绝对想使用 JavaScript,那么您需要创建一个闭包来修改el使用立即调用的函数表达式的范围:

window.onload = function () {

    var elArray = document.getElementsByTagName("a");
    if (elArray != null && elArray.length > 0) {
        for (var count = 0; count < elArray.length; count++) {
            var el = elArray[count];
            (function(el) {
            // el in here is different to el outside since the parameter shadows it
            // you could give them different names - or not declare an el variable outside - to make the difference clearer
            if (el.addEventListener) {
                el.addEventListener("mouseover", function () {
                    el.style.textDecoration = 'underline'
                }, false);
                el.addEventListener("mouseout", function () {
                    el.style.textDecoration = 'none'
                }, false);
            } else {
                el.attachEvent('onmouseover', function () {
                    el.style.textDecoration = 'underline'
                });
                el.attachEvent('onmouseout', function () {
                    el.style.textDecoration = 'none'
                });
            }
            })(el);

        } //for
    } //if
}; //end of window.onload

该匿名函数内部的更改范围,el因此它确实引用el了循环的每次迭代的值for

于 2013-04-16T10:27:27.793 回答
2

您使用的变量el不是循环迭代的本地变量,因此在触发事件处理程序时它将具有最后一个值。

使用立即调用的函数来创建一个范围,其中每次迭代都会获得它自己的变量,其中包含该迭代的元素:

window.onload = function (){

  var elArray = document.getElementsByTagName("a");
  if(elArray != null && elArray.length > 0){
    for(var count=0; count < elArray.length; count++){

      (function(el){

        if (el.addEventListener) {
          el.addEventListener("mouseover", function (){el.style.textDecoration = 'underline'}, false);
          el.addEventListener("mouseout", function (){el.style.textDecoration = 'none'}, false);
        } else {
          el.attachEvent('onmouseover',function (){el.style.textDecoration = 'underline'});
          el.attachEvent('onmouseout',function (){el.style.textDecoration = 'none'});
        }

      })(elArray[count]);

    }//for
  }//if
};//end of window.onload

但是,对于这种特定效果,您可以只使用 CSS:

a { text-decoration: none; }
a:hover { text-decoration: underline; }
于 2013-04-16T10:30:12.363 回答
2

您可以通过使用简单的 CSS 来做到这一点:

a {
    text-decoration: none;
}

a:hover {
    text-decoration: underline;
}

如果可以通过 CSS 完成,请不要使用 javascript 来麻烦浏览器。

于 2013-04-16T10:27:04.847 回答