簡體   English   中英

javascript - for 循環 - 僅每隔一個事件監聽器工作

[英]javascript - for loop - only every second event listener working

我對 web 設計非常陌生,所以我確定我在這里做了一些愚蠢的事情,但我真的很好奇我做錯了什么,我正在做一個在線 udemy 課程,由於某種原因,我生成的 li 的每一次迭代似乎都有我的事件監聽器已附加,我無法為我的生活找出原因。 我假設在添加事件偵聽器時它與我的“this”有關,我試圖更改為 listObjects[i].classList.toggle 但它只是拋出了一個錯誤,但是如果我執行 this.classList.add 就足夠奇怪了(“完成”)它完美地工作。 提前致謝!

 var enterBtn = document.querySelectorAll("button")[0]; var cancelBtn = document.querySelectorAll("button")[1]; var ul = document.querySelector("ul"); var listObjects function addList(todo) { var li = document.createElement("li"); li.appendChild(document.createTextNode(todo)); ul.appendChild(li); listObjects = document.querySelectorAll("li"); setListDone(); } enterBtn.addEventListener("click", function() { var listData = document.querySelector("input").value; addList(listData); }); cancelBtn.addEventListener("click", function() { ul.innerHTML = " "; }); function setListDone() { for (i = 0; i < listObjects.length; i++) { listObjects[i].addEventListener("click", function() { this.classList.toggle("done"); }); } }
 .done { text-decoration: line-through; }
 <h1>Todo List</h1> <input type="text"> <button>Enter</button> <button>Cancel</button> <ul> </ul>

您永遠不會刪除舊的事件偵聽器,因此任何具有偶數索引的東西都會被切換兩次(或四次,或其他任何東西)並最終以與開始時相同的 state 結束。 如果您先清除舊的事件偵聽器(或僅將它們添加到新創建的元素中),問題就會消失:

 var enterBtn = document.querySelectorAll("button")[0]; var cancelBtn = document.querySelectorAll("button")[1]; var ul = document.querySelector("ul"); var listObjects function addList(todo) { var li = document.createElement("li"); li.appendChild(document.createTextNode(todo)); ul.appendChild(li); listObjects = document.querySelectorAll("li"); setListDone(); } enterBtn.addEventListener("click", function() { var listData = document.querySelector("input").value; addList(listData); }); cancelBtn.addEventListener("click", function() { ul.innerHTML = " "; }); function setListDone() { for (i = 0; i < listObjects.length; i++) { listObjects[i].removeEventListener("click", liClickHandler); listObjects[i].addEventListener("click", liClickHandler); } } function liClickHandler() { this.classList.toggle("done"); }
 .done { text-decoration: line-through; }
 <h1>Todo List</h1> <input type="text"> <button>Enter</button> <button>Cancel</button> <ul> </ul>

原因是您使用setListDoneclick分配給所有li 因此,當您添加第二個li時,它也會將click分配給first li 因此,當您單擊第一個li時,它將調用click twice 此外,如果您添加第三個li ,那么在first li單擊時,它將調用click three times

要解決問題,您只需將新創建的li傳遞給setListDone並更新您的setListDone ,如下所示。

function setListDone(li) {
  li.addEventListener("click", function() {
    this.classList.toggle("done");
  });
}

測試下面的完整代碼。

 var enterBtn = document.querySelectorAll("button")[0]; var cancelBtn = document.querySelectorAll("button")[1]; var ul = document.querySelector("ul"); var listObjects function addList(todo) { var li = document.createElement("li"); li.appendChild(document.createTextNode(todo)); ul.appendChild(li); listObjects = document.querySelectorAll("li"); setListDone(li); } enterBtn.addEventListener("click", function() { var listData = document.querySelector("input").value; addList(listData); }); cancelBtn.addEventListener("click", function() { ul.innerHTML = " "; }); function setListDone(li) { li.addEventListener("click", function() { this.classList.toggle("done"); }); }
 .done { text-decoration: line-through; }
 <h1>Todo List</h1> <input type="text"> <button>Enter</button> <button>Cancel</button> <ul> </ul>

每次將項目添加到列表時,都會為每個項目添加事件偵聽器。 這就是為什么其中一些被觸發兩次或更多事件的原因。

listObjects[i].addEventListener("click", function() {
  this.classList.toggle("done");
});

簡單的解決方案如下。

每次將元素添加到列表時,您只需要將事件偵聽器添加到單個<li>

 var enterBtn = document.querySelectorAll("button")[0]; var cancelBtn = document.querySelectorAll("button")[1]; var ul = document.querySelector("ul"); var listObjects function addList(todo) { var li = document.createElement("li"); li.appendChild(document.createTextNode(todo)); // Here you add the listener to just created list item li.addEventListener("click", function() { this.classList.toggle("done"); }); ul.appendChild(li); } enterBtn.addEventListener("click", function() { var listData = document.querySelector("input").value; addList(listData); }); cancelBtn.addEventListener("click", function() { ul.innerHTML = " "; });
 .done { text-decoration: line-through; }
 <h1>Todo List</h1> <input type="text"> <button>Enter</button> <button>Cancel</button> <ul> </ul>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM