簡體   English   中英

JavaScript-將事件偵聽器添加到對象數組

[英]JavaScript - Adding event listener to an array of objects

我是JavaScript語言的新手,所以請幫助我了解該問題出了哪些問題。 我試圖在單擊列表項時打開和關閉完成的類 但是,我收到此“未捕獲的TypeError:無法讀取HTMLLIElement處未定義的屬性'classList'”錯誤。

 var li = document.querySelectorAll("li"); for (var i = 0; i < li.length; i++) { li[i].addEventListener("click", function() { li[i].classList.toggle("done"); }) } 
 .done { text-decoration: line-through; } 
 <h1>Shopping List</h1> <ul style="list-style-type:square"> <li>Pencil</li> <li>Paper</li> <li>Eraser</li> <li>Table Lamp</li> <li>Comb</li> </ul> 

更改

li[i].classList.toggle("done");

this.classList.toggle("done");

...否則,在事件回調中,您將始終以i的最后一個值表示的li為目標,而不是單擊的那個。

為了提高代碼的性能,可以使用事件委托 使用這種技術,您只需要向容器(在本例中為ul)中添加一次偵聽器,所有子代都可以訪問它。 然后,您可以使用event.target屬性來定位每個li項目:

var ul = document.querySelector("ul");
ul.addEventListener('click', function(event){
  event.target.classList.toggle("done");
});

添加事件監聽器時,您正在創建一個閉包。 每個事件處理程序在其范圍內都有變量i 不幸的是,它是相同的變量i ,它由您的for循環遞增。

在循環結束時,每個事件處理程序在其范圍內都有一個變量i其值現在為6。這導致在觸發事件時未定義li[i]

您可以通過以下方法解決此問題:

  • 不要在處理程序中使用i ,例如通過使用提供的event變量來引用事件。 然后,檢索目標元素:

 var li = document.querySelectorAll("li"); for (var i = 0; i < li.length; i++) { li[i].addEventListener("click", function(event) { event.target.classList.toggle("done"); }) } 
 .done { text-decoration: line-through; } 
 <h1>Shopping List</h1> <ul style="list-style-type:square"> <li>Pencil</li> <li>Paper</li> <li>Eraser</li> <li>Table Lamp</li> <li>Comb</li> </ul> 

  • 在for循環中使用let而不是var聲明i 這將導致您的每個閉包與i具有不同的綁定:

 var li = document.querySelectorAll("li"); for (let i = 0; i < li.length; i++) { li[i].addEventListener("click", function() { li[i].classList.toggle("done"); }) } 
 .done { text-decoration: line-through; } 
 <h1>Shopping List</h1> <ul style="list-style-type:square"> <li>Pencil</li> <li>Paper</li> <li>Eraser</li> <li>Table Lamp</li> <li>Comb</li> </ul> 

  • 將事件偵聽器附加到UL。 這將是我的最愛:

 var ul = document.querySelector("ul"); ul.addEventListener("click", function(event) { event.target.classList.toggle("done"); }, true); 
 .done { text-decoration: line-through; } 
 <h1>Shopping List</h1> <ul style="list-style-type:square"> <li>Pencil</li> <li>Paper</li> <li>Eraser</li> <li>Table Lamp</li> <li>Comb</li> </ul> 

閱讀有關JavaScript閉包的更多信息。

 //using for of loop var li = document.querySelectorAll("li"); for (var i of li) { i.addEventListener('click', function(e) { e.target.classList.toggle("done"); }) } 
 .done { text-decoration: line-through; } 
 <h1>Shopping List</h1> <ul style="list-style-type:square"> <li>Pencil</li> <li>Paper</li> <li>Eraser</li> <li>Table Lamp</li> <li>Comb</li> </ul> 

暫無
暫無

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

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