Ich versuche, ein Ereignis beim Ändern des Listeners zu einer Liste von Kontrollkästchen hinzuzufügen, sodass beim Aktivieren der Beschriftungstext durchgestrichen wird. Ich kann nicht herausfinden, was ich falsch mache.

let todoItem = document.querySelectorAll('.container');
let checkItem = document.querySelectorAll('.checkItem');

for (let i = 0; i < checkItem.length; i += 1) {
  for (let k = 0; k < todoItem.length; k += 1) {
    checkItem[i].onchange = () => {
      if (checkItem[i].checked === true) {
        todoItem[k].style.textDecoration = 'line-through';
      } else {
        todoItem[k].style.textDecoration = 'none';
      }
    }
  }
}
<div>
  <label class="container">one
  <input type="checkbox" class="checkItem">
 </label>

  <label class="container">two
  <input type="checkbox" class="checkItem">
 </label>

  <label class="container">three
  <input type="checkbox" class="checkItem">
 </label>
</div>

.

0
Ojay 7 Feb. 2020 im 18:56

3 Antworten

Beste Antwort

Hier sind also ein paar Dinge los. Zunächst durchlaufen Sie zwei Schleifen und sagen im Grunde: Stellen Sie für jedes Kontrollkästchen den Listener so ein, dass Label 1 umgeschaltet wird. Setzen Sie dann den Listener auf Label 2. Dann Label 3. Zweitens, indem Sie checkItem[i].onchange = [Fn] zuweisen, werden Sie ' Überschreiben Sie alle vorherigen Werte, weshalb nur das letzte Etikett anstelle aller drei umgeschaltet wird. Das Ergebnis Ihrer Schleifen sieht also im Wesentlichen so aus:

  1. Stellen Sie den Listener von Checkbox 1 so ein, dass Label 1 umgeschaltet wird.
  2. Stellen Sie den Listener von Kontrollkästchen 1 auf "Label 2" um und überschreiben Sie den vorherigen Listener.
  3. Stellen Sie den Listener von Kontrollkästchen 1 auf "Label 3" um und überschreiben Sie den vorherigen Listener.
  4. Stellen Sie den Listener von Checkbox 2 so ein, dass Label 1 umgeschaltet wird.
  5. Stellen Sie den Listener von Kontrollkästchen 2 auf "Label 2" um und überschreiben Sie den vorherigen Listener.
  6. Stellen Sie den Listener von Kontrollkästchen 2 auf "Label 3" um und überschreiben Sie den vorherigen Listener.
  7. Stellen Sie den Listener von Checkbox 3 so ein, dass Label 1 umgeschaltet wird.
  8. Stellen Sie den Listener von Kontrollkästchen 3 auf "Label 2" um und überschreiben Sie den vorherigen Listener.
  9. Stellen Sie den Listener von Kontrollkästchen 3 auf "Label 3" um und überschreiben Sie den vorherigen Listener.

Wenn Sie die innere Schleife entfernen und nur denselben Index wiederverwenden, wird Ihr Problem gelöst. Ich würde jedoch empfehlen, noch einen Schritt weiter zu gehen und den Ereignis-Listener mithilfe von addEventListener zuzuweisen. Auf diese Weise können zukünftig zusätzliche Listener hinzugefügt werden, ohne die vorhandene Funktionalität zu beeinträchtigen. Beispiel unten.

let todoItem = document.querySelectorAll('.container');
let checkItem = document.querySelectorAll('.checkItem');

for (let i = 0; i < checkItem.length; i += 1) {
  checkItem[i].addEventListener('change', () => {
    if (checkItem[i].checked === true) {
      todoItem[i].style.textDecoration = 'line-through';
    } else {
      todoItem[i].style.textDecoration = 'none';
    }
  });
}
<div>
  <label class="container">one
  <input type="checkbox" class="checkItem">
 </label>

  <label class="container">two
  <input type="checkbox" class="checkItem">
 </label>

  <label class="container">three
  <input type="checkbox" class="checkItem">
 </label>
</div>
1
Quangdao Nguyen 7 Feb. 2020 im 16:09

Ihre innere Schleife ist das Problem. Sie iterieren alle Beschriftungen bis zur letzten und wenden diese als onchange -Ereignis auf jedes Kontrollkästchen an, sodass die letzte Beschriftung immer die Zeile durchläuft, unabhängig davon, welches Kontrollkästchen aktiviert ist. Entfernen Sie die innere Schleife, da genau so viele Beschriftungen vorhanden sind wie Kontrollkästchen:

let todoItem = document.querySelectorAll('.container');
let checkItem = document.querySelectorAll('.checkItem');

for (let i = 0; i < checkItem.length; i += 1) {
    checkItem[i].onchange = () => {
      if (checkItem[i].checked === true) {
        todoItem[i].style.textDecoration = 'line-through';
      } else {
        todoItem[i].style.textDecoration = 'none';
      }
    }
}

Working jsfiddle: https://jsfiddle.net/rbcLm03g/

1
Ryan Wilson 7 Feb. 2020 im 16:01

Erweitern Sie den Code nicht zu stark, schreiben Sie den Code wie folgt:

let checkItem = document.querySelectorAll('.checkItem');
[...checkItem].forEach((cb)=>{ // Array.from().forEach
  cb.addEventListener("change", function(){
    if(this.checked===true){
      this.parentElement.style.textDecoration = 'line-through';
    }else{
      this.parentElement.style.textDecoration = 'none';
    }
  });
});
<div>
  <label class="container">one
  <input type="checkbox" class="checkItem">
 </label>

  <label class="container">two
  <input type="checkbox" class="checkItem">
 </label>

  <label class="container">three
  <input type="checkbox" class="checkItem">
 </label>
</div>
1
Ritesh Khandekar 7 Feb. 2020 im 16:36