I tried to color the text I clicked on by gave them a class and besides the text I click on the original color is back again, but when I click on the text twice the class can’t be removed. I use toggle class for this issue but doesn’t work.
.red { color: red; }
<ul> <li class="txt">Lorem ipsum dolor.</li> <li class="txt">Lorem ipsum dolor.</li> <li class="txt">Lorem ipsum dolor.</li> </ul>
const txts = document.querySelectorAll('.txt'); const txtColor =(txt)=> { txt.addEventListener('click', e => { if(e.target.classList.contains('txt')) { txts.forEach(txt => txt.classList.remove('red')); e.target.classList.toggle('red'); } }); } txtColor(document.querySelector('ul'));
Advertisement
Answer
Cache the main list element, and the list items, and then attach one listener to the list element so you can use Event delegation to catch item click events as they “bubble up” the DOM.
When an item is clicked remove the red
class from all the items and , depending on the conditional parameter you pass to toggle
, (does the classList
contain a red
class) toggle
the red
class.
// Cache the elements const ul = document.querySelector('ul'); const lis = document.querySelectorAll('.txt'); // Add a listener to the list ul.addEventListener('click', handleClick, false); function handleClick(e) { // Destructure the nodeName and classList from the // the element we clicked on const { nodeName, classList } = e.target; // Check if it's a list item if (nodeName === 'LI') { // Does the list item contain a red class? const isRed = classList.contains('red'); // Remove all the red classes from all the items lis.forEach(li => li.classList.remove('red')); // And depending on the answer to `isRed` // toggle the class on or off classList.toggle('red', !isRed); } }
.red { color: red; } .txt:hover { cursor: pointer; }
<ul> <li class="txt">Lorem ipsum dolor.</li> <li class="txt">Lorem ipsum dolor.</li> <li class="txt">Lorem ipsum dolor.</li> </ul>
Additional documentation