You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让EventListener作用于全部列表项?当前仅最后一项生效

问题:EventListener仅对最后一个列表项生效

不知为何我的EventListener仅对最后一个列表项生效,有人能帮忙解决吗?

以下是我当前的代码:

(function(){
    // All items we'd like to add
    var navItems = [
        {href: 'http://instagram.com', text: 'Instagram'},
        {href: 'http://twitter.com', text: 'Twitter'},
        {href: 'http://facebook.com', text: 'Facebook'},
        {href: 'http://google.com', text: 'Google'},
        {href: 'https://youtube.com', text: 'Youtube'}
    ];

    // A few variables for use later
    var navElem = document.createElement("nav"),
        navList = document.createElement("ul"), 
        navItem, navLink;
        navElem.setAttribute('style','');
        navList.setAttribute('style','height: 100px;display:flex;');

    navElem.appendChild(navList);

    // Cycle over each nav item
    for (var i = 0; i < navItems.length; i++) {
        // Create a fresh list item, and anchor
        navItem = document.createElement("li");
        navLink = document.createElement("a");
        navItem.setAttribute('style','list-style-type:none; padding-top: 8px;background-color:rgb(209, 157, 12);margin: 30px 20px;border-radius:50px;');
        navLink.setAttribute('style','padding:0px 20px;text-decoration:none;font-size:20px;color:white;');

        // Set properties on anchor
        navLink.href = navItems[i].href;
        navLink.innerHTML = navItems[i].text;

        // Add anchor to list item, and list item to list
        navItem.appendChild(navLink);
        navList.appendChild(navItem);
    }
    
    navItem.addEventListener('mouseenter', () =>
    navItem.setAttribute('style','list-style-type:none; padding-top: 8px;background-color:rgba(209, 157, 12, 0.644);margin: 30px 20px;border-radius:50px;'));
    navItem.addEventListener('mouseleave', () =>
    navItem.setAttribute('style','list-style-type:none; padding-top: 8px;background-color:rgb(209, 157, 12);margin: 30px 20px;border-radius:50px;'));

    navList.children[0].className = "current";

    // Add list to body (or anywhere else)
    window.onload = function () {
        document.body.before(navElem);
    }

}());

问题原因

你在循环外部给navItem绑定事件,但navItem是循环中反复赋值的变量,循环结束后它仅指向最后一个创建的列表项,因此事件只会绑定到最后一个元素上。

解决方案

方案一:将事件绑定移入循环内部

每次创建完navItem后立即绑定事件,确保每个列表项都能绑定到对应事件:

(function(){
    // All items we'd like to add
    var navItems = [
        {href: 'http://instagram.com', text: 'Instagram'},
        {href: 'http://twitter.com', text: 'Twitter'},
        {href: 'http://facebook.com', text: 'Facebook'},
        {href: 'http://google.com', text: 'Google'},
        {href: 'https://youtube.com', text: 'Youtube'}
    ];

    // A few variables for use later
    var navElem = document.createElement("nav"),
        navList = document.createElement("ul"), 
        navItem, navLink;
        navElem.setAttribute('style','');
        navList.setAttribute('style','height: 100px;display:flex;');

    navElem.appendChild(navList);

    // Cycle over each nav item
    for (var i = 0; i < navItems.length; i++) {
        // Create a fresh list item, and anchor
        navItem = document.createElement("li");
        navLink = document.createElement("a");
        navItem.setAttribute('style','list-style-type:none; padding-top: 8px;background-color:rgb(209, 157, 12);margin: 30px 20px;border-radius:50px;');
        navLink.setAttribute('style','padding:0px 20px;text-decoration:none;font-size:20px;color:white;');

        // Set properties on anchor
        navLink.href = navItems[i].href;
        navLink.innerHTML = navItems[i].text;

        // Add anchor to list item, and list item to list
        navItem.appendChild(navLink);
        navList.appendChild(navItem);

        // 绑定事件到当前创建的navItem
        navItem.addEventListener('mouseenter', () =>
        navItem.setAttribute('style','list-style-type:none; padding-top: 8px;background-color:rgba(209, 157, 12, 0.644);margin: 30px 20px;border-radius:50px;'));
        navItem.addEventListener('mouseleave', () =>
        navItem.setAttribute('style','list-style-type:none; padding-top: 8px;background-color:rgb(209, 157, 12);margin: 30px 20px;border-radius:50px;'));
    }

    navList.children[0].className = "current";

    // Add list to body (or anywhere else)
    window.onload = function () {
        document.body.before(navElem);
    }

}());

方案二:使用事件委托(更高效)

无需给每个列表项单独绑定事件,将事件绑定到父元素navList上,利用事件冒泡机制处理,后续新增列表项也能自动生效:

(function(){
    // All items we'd like to add
    var navItems = [
        {href: 'http://instagram.com', text: 'Instagram'},
        {href: 'http://twitter.com', text: 'Twitter'},
        {href: 'http://facebook.com', text: 'Facebook'},
        {href: 'http://google.com', text: 'Google'},
        {href: 'https://youtube.com', text: 'Youtube'}
    ];

    // A few variables for use later
    var navElem = document.createElement("nav"),
        navList = document.createElement("ul"), 
        navItem, navLink;
        navElem.setAttribute('style','');
        navList.setAttribute('style','height: 100px;display:flex;');

    navElem.appendChild(navList);

    // Cycle over each nav item
    for (var i = 0; i < navItems.length; i++) {
        // Create a fresh list item, and anchor
        navItem = document.createElement("li");
        navLink = document.createElement("a");
        navItem.setAttribute('style','list-style-type:none; padding-top: 8px;background-color:rgb(209, 157, 12);margin: 30px 20px;border-radius:50px;');
        navLink.setAttribute('style','padding:0px 20px;text-decoration:none;font-size:20px;color:white;');

        // Set properties on anchor
        navLink.href = navItems[i].href;
        navLink.innerHTML = navItems[i].text;

        // Add anchor to list item, and list item to list
        navItem.appendChild(navLink);
        navList.appendChild(navItem);
    }

    // 事件委托:绑定到父元素navList
    navList.addEventListener('mouseenter', (e) => {
        // 确认触发事件的是li元素或其子元素a
        const targetItem = e.target.tagName === 'LI' ? e.target : e.target.parentElement;
        if(targetItem.tagName === 'LI'){
            targetItem.setAttribute('style','list-style-type:none; padding-top: 8px;background-color:rgba(209, 157, 12, 0.644);margin: 30px 20px;border-radius:50px;');
        }
    });

    navList.addEventListener('mouseleave', (e) => {
        const targetItem = e.target.tagName === 'LI' ? e.target : e.target.parentElement;
        if(targetItem.tagName === 'LI'){
            targetItem.setAttribute('style','list-style-type:none; padding-top: 8px;background-color:rgb(209, 157, 12);margin: 30px 20px;border-radius:50px;');
        }
    });

    navList.children[0].className = "current";

    // Add list to body (or anywhere else)
    window.onload = function () {
        document.body.before(navElem);
    }

}());

方案三:用CSS实现Hover效果(最简洁推荐)

完全不需要JS,直接用CSS的:hover伪类实现鼠标悬停效果,代码更简洁高效:

nav ul {
    height: 100px;
    display:flex;
}
nav ul li {
    list-style-type:none; 
    padding-top: 8px;
    background-color:rgb(209, 157, 12);
    margin: 30px 20px;
    border-radius:50px;
}
nav ul li:hover {
    background-color:rgba(209, 157, 12, 0.644);
}
nav ul li a {
    padding:0px 20px;
    text-decoration:none;
    font-size:20px;
    color:white;
}

对应的JS代码可移除所有事件绑定和内联style设置:

(function(){
    // All items we'd like to add
    var navItems = [
        {href: 'http://instagram.com', text: 'Instagram'},
        {href: 'http://twitter.com', text: 'Twitter'},
        {href: 'http://facebook.com', text: 'Facebook'},
        {href: 'http://google.com', text: 'Google'},
        {href: 'https://youtube.com', text: 'Youtube'}
    ];

    // A few variables for use later
    var navElem = document.createElement("nav"),
        navList = document.createElement("ul"), 
        navItem, navLink;

    navElem.appendChild(navList);

    // Cycle over each nav item
    for (var i = 0; i < navItems.length; i++) {
        // Create a fresh list item, and anchor
        navItem = document.createElement("li");
        navLink = document.createElement("a");

        // Set properties on anchor
        navLink.href = navItems[i].href;
        navLink.innerHTML = navItems[i].text;

        // Add anchor to list item, and list item to list
        navItem.appendChild(navLink);
        navList.appendChild(navItem);
    }

    navList.children[0].className = "current";

    // Add list to body (or anywhere else)
    window.onload = function () {
        document.body.before(navElem);
    }

}());

内容的提问来源于stack exchange,提问作者carlsby

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 19:35:20