如何让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
相关产品推荐
相关产品推荐

