I am actually trying to add class (Selected) to the li when clicked and remove Class from neighbour li.
Issue is it doesn't work when there is 2 ul, the below code only work on the 1st ul or when i click on the li of the second li, first li active gets removed
const menuLis = document.querySelectorAll("#top-nav > li"); for (let li of menuLis) { li.addEventListener("click", function(){ // 1. Remove Class from All Lis for (let li of menuLis) { li.classList.remove('selected'); } // 2. Add Class to Relevant Li this.classList.add('selected'); }); }
.selected{color:red}
<ul id='top-nav'> <li>Coffee</li> <li>Tea</li> <li>Milk</li> </ul> <ul id='top-nav'> <li>Coffee</li> <li>Tea</li> <li>Milk</li> </ul>
Thank you for the help
You need to use a class, as well to separate handling for each ul for it to properly work:
const menuUls = document.querySelectorAll('.top-nav'); for (const ul of menuUls) { const menuLis = ul.querySelectorAll('li'); for (const li of menuLis) { li.addEventListener('click', function () { // 1. Remove Class from All Lis for (let li of menuLis) { li.classList.remove('selected'); } // 2. Add Class to Relevant Li this.classList.add('selected'); }); } }
.selected{color:red}
<ul class='top-nav'> <li>Coffee</li> <li>Tea</li> <li>Milk</li> </ul> <ul class='top-nav'> <li>Coffee</li> <li>Tea</li> <li>Milk</li> </ul>
You can select the element's siblings
, and remove the selected
class.
const menuLis = document.querySelectorAll(".top-nav > li"); for (let li of menuLis) { li.addEventListener("click", function(){ for (let sibling of this.parentNode.children) { sibling.classList.remove('selected'); } this.classList.add('selected'); }); }
.selected{color:red}
<ul class='top-nav'> <li>Coffee</li> <li>Tea</li> <li>Milk</li> </ul> <ul class='top-nav'> <li>Coffee</li> <li>Tea</li> <li>Milk</li> </ul>
Ids must be unique - one per page only, so you should use a class instead.
Another thing to think about is: on every click you're adding new listeners to all the list items which might be okay for a small example but might prove inefficient at scale.
An alternative method would be to use event delegation - attach one listener to each parent element, the list item, and check the information on the event target to update its list items.
const menus = document.querySelectorAll('.top-nav'); menus.forEach(menu => { menu.addEventListener('click', handleClick, false); }); function handleClick(e) { const { nodeName, parentNode } = e.target; // If the clicked element is a list item if (nodeName === 'LI') { // Find all the list items of the current list const items = parentNode.querySelectorAll('li') // Remove the class from each, and then add the // class to the element that was clicked items.forEach(i => i.classList.remove('selected')); e.target.classList.add('selected'); } }
.selected { color:red; } li:hover { cursor: pointer; }
<ul class="top-nav"> <li>Coffee</li> <li>Tea</li> <li>Milk</li> </ul> <ul class="top-nav"> <li>Coffee</li> <li>Tea</li> <li>Milk</li> </ul>
Additional documentation
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.