如何使用Vanilla JS将元素悬停在另一个元素上时更改元素的状态

时间:2019-07-31 22:29:05

标签: javascript html css hover queryselector

我正在尝试使用mouseover事件和querySelectorAll方法将项​​目悬停在另一个项目上时进行更改。坦白说,我不知道我的代码有什么问题,有人帮忙吗?

var navBar = document.getElementById('nav');
var navLiAnchor = navBar.querySelectorAll('ul > li > a');
var navIcons = navBar.querySelectorAll('ul > li > span > i');

for (var i = 1; i < navIcons.length; i++) {
    navIcons[i].addEventListener("mouseover", function() {
        if(navIcons[i].style.color == 'gray'){
        navLiAnchor[i].style.color = 'gray';
        } else {
            navLiAnchor[i].style.color = 'lightgray';
        }
    });
}

1 个答案:

答案 0 :(得分:1)

问题可能是您在for循环中添加了事件侦听器。通常,这被认为是不好的做法,您的情况是一个很好的理由,因为它会导致错误。

请参阅:https://gomakethings.com/why-you-shouldnt-attach-event-listeners-in-a-for-loop-with-vanilla-javascript/

  

i变量不在范围内#每次循环迭代后,i变量都会增加1。在事件侦听器回调函数的范围内,该值不会保持恒定。它会改变。

重构代码,以便事件处理程序不引用父作用域中的计数器变量。在处理程序中,您可以使用this来引用目标元素(也可以使用Event.target):

var navBar = document.getElementById('nav');
var navLiAnchor = navBar.querySelectorAll('ul > li > a');
var navIcons = navBar.querySelectorAll('ul > li > span > i');

for (var i = 0; i < navIcons.length; i++) {
    navIcons[i].addEventListener("mouseover", function() {
        var idx = navIcons.indexOf(this);
        if(this.style.color == 'gray'){
            navLiAnchor[idx].style.color = 'gray';
        } else {
            navLiAnchor[idx].style.color = 'lightgray';
        }
    });
}

(此外,正如@SmujMaiku指出的那样,您可能希望循环从第一个元素索引0开始。)