2015-01-27 13 views
34

Từ MDN cho NodeList:Khi nào NodeList hoạt động và khi nào nó tĩnh?

Trong một số trường hợp, NodeList là một bộ sưu tập sống, có nghĩa là thay đổi trong DOM được phản ánh trong bộ sưu tập. Ví dụ, Node.childNodes là live:

var parent = document.getElementById('parent'); 
var child_nodes = parent.childNodes; 
console.log(child_nodes.length); // let's assume "2" 
parent.appendChild(document.createElement('div')); 
console.log(child_nodes.length); // should output "3" 

Trong trường hợp khác, các NodeList là một bộ sưu tập tĩnh, có nghĩa là bất kỳ sự thay đổi tiếp theo trong DOM không ảnh hưởng đến nội dung của bộ sưu tập. document.querySelectorAll trả về một NodeList tĩnh.

Vì vậy .... loại gây phiền nhiễu! Có bất kỳ tham chiếu trung tâm nào về phương thức nào trả về danh sách trực tiếp và danh sách nào trả về danh sách tĩnh, mà không phải kiểm tra riêng cho tất cả các phần khác nhau của API DOM không? Có bất kỳ quy tắc nào tại nơi làm việc ở đây không?

+0

Kiểm tra [NodeList.js] (https://github.com/eorroe/NodeList.js) –

Trả lời

61

Thông tin về từng chi tiết phương pháp nếu nó đang hoạt động hay không, nhưng dường như không có quy ước chuẩn để xác định nó.

document.getElementsByClassName()HTMLCollection và đang phát trực tiếp.

document.getElementsByTagName()HTMLCollection và đang phát trực tiếp.

document.getElementsByName()NodeList và hoạt động.

document.querySelectorAll()NodeList và là không hoạt động.

HTMLCollection s dường như luôn sống

Một HTMLCollection là danh sách các nút. Một nút riêng lẻ có thể là được truy cập bởi chỉ mục thứ tự hoặc thuộc tính hoặc tên của nút.

Lưu ý: Các bộ sưu tập trong DOM HTML được giả định là trực tiếp có nghĩa là chúng sẽ tự động được cập nhật khi tài liệu cơ bản là thay đổi.

http://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-75708506

Vì vậy, HTML Bộ sưu tập là luôn "trong dom," trong khi một nodeList là một cấu trúc chung chung hơn có thể có hoặc không có thể trong DOM.

Đối tượng NodeList là tập hợp các nút ... Giao diện NodeList cung cấp sự trừu tượng hóa bộ sưu tập các nút của được sắp xếp, mà không cần xác định hoặc hạn chế cách thực hiện bộ sưu tập này. Các đối tượng NodeList trong DOM là trực tiếp.

http://www.w3.org/TR/DOM-Level-3-Core/core.html#td-live

Âm thanh tốt, phải không?

Bộ sưu tập là đối tượng đại diện cho danh sách các nút DOM. Bộ sưu tập có thể là trực tiếp hoặc tĩnh. Trừ khi có quy định khác, bộ sưu tập phải hoạt động.

http://www.w3.org/TR/2012/WD-dom-20120405/#collections

bộ sưu tập So tĩnh sẽ được chỉ ra như vậy trong spec. Vì vậy, theo logic này, document.querySelectorAll() là một bộ sưu tập, nhưng nó là không phải là trong DOM. Bởi vì trong khi các bộ sưu tập có thể hoặc không thể phát trực tiếp, các bộ sưu tập trong DOM phải đang hoạt động ... Sự khác biệt này không phải là siêu hữu ích.

Vâng, đây là một phương pháp nhanh để xác định xem collection có hoạt động hay không; nó gắn thêm một bản sao của một thành viên của bộ sưu tập đến DOM (vì vậy nó sẽ phù hợp với selector), và kiểm tra xem nếu độ dài thay đổi, và sau đó loại bỏ nó (vì vậy trang không bị ảnh hưởng)

function isLive(collection) { 
    if (collection.length < 1) { 
     return undefined; //inconclusivw 
    } 
    let body = document.getElementsByTagName('body')[0]; 
    let l1 = collection.length; 
    let clone = collection.item(0).cloneNode(); 
    clone.style.display = "none"; 
    body.appendChild(clone); 
    let l2 = collection.length; 
    body.removeChild(clone); 
    return l2 !== l1; 
} 

DEMO

HTML

<html><body> 
<div class="c" name="mydiv">C1</div> 
<div class="c" name="mydiv">C2</div> 
</body></html> 

JS

divs1=document.getElementsByClassName('c'); 
console.log(divs1.toString());//"[object HTMLCollection]" 


divs2=document.querySelectorAll('.c'); 
console.log(divs2.toString());//"[object NodeList]" 

divs3=document.getElementsByName('mydiv'); 
console.log(divs3.toString());//"[object NodeList"] 

console.log(isLive(divs1));//true 
console.log(isLive(divs2));//false 
console.log(isLive(divs3));//true 
+2

Xem lại điều này, đây là câu trả lời khá hay. Bạn xứng đáng một tiền thưởng. – Aerovistae

+1

@Aerovistae cảm ơn bạn rất nhiều! Tôi rất vui vì tôi đã có thể trả lời câu hỏi của bạn một cách thỏa đáng và làm như vậy, đóng góp một cái gì đó có giá trị cho cộng đồng SO lớn. Tôi thực sự đánh giá cao cử chỉ! – chiliNUT

+1

Vâng đó là một câu trả lời thực sự toàn diện cho một chủ đề HTML thực sự mơ hồ được ghi lại. Cảm ơn vì nỗ lực của bạn. – Aerovistae

2

Tôi không biết nếu có một tài liệu tham khảo trung tâm, nhưng blog post này nói:

document.getElementsByTagName(), document.getElementsByTagNameNSdocument.getElementsByClassName() là những tùy chọn chỉ có sẵn lợi nhuận mà “sống” danh sách node. Nhìn vào những phương pháp đó, bạn có thể chán nản, nhưng không được.

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