skip to Main Content

I am working on project and my goal is to toggle each individual li element by clicking toggle button.
I managed to do this so far but it’s working only on first li element.
Can you help me with this code?

<li id="liEl">Target This element</li>
<button id="Btn">toggle</button>

<li id="liEl" >Target This element</li>
<button id="Btn">toggle</button>

<li id="liEl" >Target This element</li>
<button id="Btn">toggle</button>
.done {
  text-decoration: line-through;
  text-decoration-thickness: 0.2rem;
  text-decoration-color:red;
}
Btn= document.getElementById("Btn");
liEl= document.getElementById("liEl");

const toggleDoneClass = () => {

  liEl.classList.toggle('done');
};

Btn.addEventListener('click', toggleDoneClass);

3

Answers


  1. id attribute must be unique.
    you can use class instead of that.

    HTML

    <li class="list_element">Target This element</li>
    <button class="btn">toggle</button>
    
    <li class="list_element" >Target This element</li>
    <button class="btn">toggle</button>
    
    <li class="list_element" >Target This element</li>
    <button class="btn">toggle</button>
    

    You must select all buttons and then add Event Listener to each one by a loop.

    Javascript

    var btns = document.getElementsByClassName("btn");
    
    for (let i = 0; i < btns.length; i++) {
        btns[i].addEventListener("click", () => {
             // Previous is li because li is before button
             btns[i].previousElementSibling.classList.toggle("done");
        });
    }
    

    Now this is Working.

    Login or Signup to reply.
  2. IDs should be unique in a page so maybe switch those to classes.

    If you want the buttons you should add them within the list item elements.

    You can attach one listener to the <ul> element and have that catch events from its children as they "bubble up" the DOM. (This is known as event delegation.)

    When a click event is fired you can retrieve the specific element that was clicked with event.target, check that it’s a button element, find the closest list item element to that button, and then toggle its class.

    const list = document.querySelector('ul');
    list.addEventListener('click', toggleDoneClass);
    
    function toggleDoneClass(e) {
      if (e.target.matches('button')) {
        e.target.closest('li').classList.toggle('done');
      }
    }
    .done { text-decoration: line-through; text-decoration-thickness: 0.2rem; text-decoration-color:red; }
    li button { margin-left: 0.5em; }
    <ul>
      <li class="liEl">
        Target This element
        <button type="button">Toggle</button>
      </li>
      <li class="liEl">
        Target This element
        <button type="button">Toggle</button>
      </li>
      <li class="liEl">
        Target This element
        <button type="button">Toggle</button>
      </li>
    </ul>

    But, ultimately, you don’t really need the buttons.

    const list = document.querySelector('ul');
    list.addEventListener('click', toggleDoneClass);
    
    function toggleDoneClass(e) {
      if (e.target.matches('li')) {
        e.target.classList.toggle('done');
      }
    }
    .done { text-decoration: line-through; text-decoration-thickness: 0.2rem; text-decoration-color:red; }
    li:hover { cursor: pointer; }
    <ul>
      <li class="liEl">Target This element</li>
      <li class="liEl">Target This element</li>
      <li class="liEl">Target This element</li>
    </ul>
    Login or Signup to reply.
  3. You are giving the same ids to all the buttons and li instead of id use class names

    btns= document.getElementsByClassName("btn");
    

    it will select all the classes which contain buttons

    for(let index = 0;index < btns.length; index++){
       btns[index].onclick = (evt) =>{
      evt.target.previousElementSibling.classList.toggle("done")
        }
    }
    
    

    looping all the classes on which you will click it will take that element and then get their previous child which is li and toggle class on that

    btns= document.getElementsByClassName("btn");
    
    for(let index = 0;index < btns.length; index++){
       btns[index].onclick = (evt) =>{
      evt.target.previousElementSibling.classList.toggle("done")
        }
    }
    .done {
      text-decoration: line-through;
      text-decoration-thickness: 0.2rem;
      text-decoration-color:red;
    }
    <li id="" >Target This element</li>
    <button  class="btn">toggle</button>
    
    <li id="" >Target This element</li>
    <button  class="btn">toggle</button>
    
    <li id="lEl" >Target This element</li>
    <button  class="btn">toggle</button>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search