2015-06-15 15 views
7

Mozilla tuyên bố rằng "cho vòng lặp sẽ lặp lại chính xác đối tượng NodeList". (nguồn: https://developer.mozilla.org/en-US/docs/Web/API/NodeList) Tuy nhiên, tính năng này không hoạt động trong Chrome 43. Đây có phải là tài liệu không chính xác hoặc lỗi trình duyệt không?cho truy vấn vòng lặpSelectorAll

Các sao chép mã ví dụ được sử dụng trên một trang với hộp kiểm sau:

var list = document.querySelectorAll('input[type=checkbox]'); 
for (var item of list) { 
    item.checked = true; 
} 
+0

Chúng tôi có thể có ngữ cảnh nhiều hơn một chút không? Bạn có thể cho chúng tôi một ví dụ hay bất cứ điều gì? – Xufox

+0

Tôi muốn biết chính xác những gì không hoạt động trong Chrome. Nó có ném một lỗi cú pháp không? Nó có kiểm tra không có hộp kiểm nào không? – Xufox

+2

['for..of' loops] (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of) chỉ hỗ trợ các đối tượng [được triển khai làm vòng lặp ] (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols), chứa khóa/phương thức 'Symbol.iterator'. Hiện tại, trong Chrome, 'console.log (Symbol.iterator trong danh sách); // false'. –

Trả lời

1

Kể từ khi tôi đã sử dụng thành công trong for..of Gecko để lặp NodeList s, có vẻ như đây là một lỗi trình duyệt, hoặc ít nhất là một thiếu trình duyệt .

mã làm việc thực tế từ một UserScript Tôi hiện đang sử dụng:

let llnk = document.querySelectorAll("div#threadlist a.threadtitle_unread"); 
for (let lnk of llnk) { 
    //... 
} 

(Điều này cũng sử dụng let, nhưng đó là một câu chuyện khác.)

6

Các tài liệu là chính xác, nhưng tôi sẽ không gọi một này lỗi. Thay vào đó là "tính năng chưa được triển khai".

Không có tiêu chuẩn cho điều này và vẫn còn thảo luận tích cực về cách DOM nên tích hợp với ES6. Chú ý rằng nó là rõ ràng rằngquerySelectorAll nên trả lại một cái gì đó iterable mà có thể được sử dụng trong một vòng lặp for of (tùy theo từng nhu cầu mong muốn phổ biến), nhưng nó không rõ ràng cách đó nên xảy ra (Hãy NodeList thực hiện các giao diện Iterable? Hãy để một số Elements collection subclass Array?).

1

Hãy thử sử dụng Array.prototype.entries()

var list = [].entries.call(document.querySelectorAll("input[type=checkbox]")); 
 

 
for (item of list) { 
 
    item[1].checked = true; 
 
};
<input type="checkbox" /><input type="checkbox" />

Bạn cũng có thể sử dụng Array.prototype.values()

var list = [].values.call(document.querySelectorAll("input[type=checkbox]")); 
 

 
for (item of list) { 
 
    item.checked = true; 
 
};
<input type="checkbox" /><input type="checkbox" />

0

Bạn có thể sử dụng Array.from

let _list = document.querySelectorAll('input[type=checkbox]'); 

let list = Array.from(_list); 

for (let item of list) { 
    //... just like an array 
    item.checked = true 
} 

hoặc ngay hơn

let list = document.querySelectorAll('input[type=checkbox]'); 

for (let item of Array.from(list)) { 
    item.checked = true 
} 

Lưu ý quan trọngArray.from đã được giới thiệu trong phiên bản Chrome 45 source.

+0

Làm thế nào là tốt hơn? Bạn cần phải gọi Array.from mỗi lần. –

+0

Vâng, đúng là bạn phải gọi 'Array.from' mỗi lần (và có thể bao gồm một polyfill cho điều đó), nhưng với phương pháp này bạn không cố gắng mở rộng DOM. –

+0

Điều này có liên quan gì đến việc mở rộng DOM? –

0

Đây là những gì tôi làm, cho một cách tiếp cận khác nhau

Array.prototype.forEach.call(document.querySelectorAll("input[type=checkbox]"),function(ele,idx) 
{ 
    ele.checked = true; 
} 

tốt từ IE9 trở lên

0

hỗ trợ Native Symbol.iterator cho NodeListadded đến WHATWG's DOM spec trong năm 2014.

Thật không may, Chrome 51 là phiên bản đầu tiên của Chrome để hỗ trợ nó và bản Beta của nó vừa được phát hành tại thời điểm viết câu trả lời này. Ngoài ra, không có hỗ trợ trong bất kỳ phiên bản nào của Internet Explorer hoặc Edge.

Để thêm Symbol.iterator hỗ trợ cho NodeList trong tất cả các trình duyệt mã của bạn, chỉ cần sử dụng polyfill sau:

NodeList.prototype[Symbol.iterator] = Array.prototype[Symbol.iterator]; 
1

Dưới đây là thêm một giải pháp cho thời hiện đại:

[...document.querySelectorAll("input[type=checkbox]")].forEach(node => { 
    node.textContent = "foo"; 
}); 

này có lợi thế của spread operator được hỗ trợ trong Google Chrome 46+, Firefox 16+ và Edge và chỉ để giải trí arrow function.

+0

Mục đích của việc xây dựng lại mảng là gì? –

+0

Kết quả của 'querySelectorAll' là một NodeList, không phải là một mảng. Bằng cách chuyển đổi nó, chúng ta có thể dễ dàng lặp lại nó. –

+0

Điều gì làm cho nó khác biệt bây giờ? Cả hai đều có thể lặp lại. –

0

Tôi gặp sự cố này. Hóa ra của tôi đã được gây ra bằng cách gọi Promise.all() với các tham số thay vì một mảng. Ví dụ:

Trước: Promise.all(p1, p2)

Sau: Promise.all([p1, p2])

Hope this helps một ai đó.

+0

Điều này có liên quan gì với NodeList? –

Các vấn đề liên quan