Home > Back-end >  can't remove class after click again
can't remove class after click again

Time:11-07

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')); 

CodePudding user response:

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>
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

Additional documentation

CodePudding user response:

Using jQuery, I could make this work.

$('ul li').on('click', function(){
  $(this).toggleClass('text')
});
.text {
color:red
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul>
  <li class="txt">Lorem ipsum dolor.</li>
  <li class="txt">Lorem ipsum dolor.</li>
  <li class="txt">Lorem ipsum dolor.</li>
</ul>
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

CodePudding user response:

Here's my answer. Please see the comments in each section.

const txts = document.querySelectorAll('.txt');

const txtColor = (txt) => {
  // click on li item
  txt.addEventListener('click', e => { 
    // if target contains class txt, which in case, it's hard coded
    // this will always return true
    if (e.target.classList.contains('txt')) {
      // remove red class for each list item with class txt
      // in this line, it removes every 'red' class on each list item
      txts.forEach(txt => txt.classList.remove('red'));
      // Then toggle 'red' class if it's not present on the target
      // Toggle does as it say, if its not present, it adds the token
      // if it's present, it removes it.
      // since the statement above ALWAYS removes the red class,
      // Toggle will only always add the 'red' class
      
    }
    e.target.classList.toggle('red');
  });
}

txtColor(document.querySelector('ul'));

If I'm right, I think this is what you're trying to do.

document.querySelector('ul').addEventListener("click", (e) => {
    // if target doesn't contain red class, then remove all red class from the list
    
    if(!e.target.classList.contains("red")) {
        document.querySelectorAll("li").forEach(e => e.classList.remove("red"))
    }
    // toggle red class to the target
    e.target.classList.toggle("red")
})
  • Related