1. DOM Node Lists trong JavaScript là gì?

NodeList là các đối tượng là tập hợp các nút. Một NodeList cũng có thể bao gồm tất cả các nút trong một tập hợp các nút được chọn cụ thể. Nó thường được trả về bởi các thuộc tính như Node.childNodes và các phương thức như document.querySelectorAll() . Một NodeList có thể được chọn bằng cách sử dụng phương thức getElementsByTagName() của đối tượng document trong Js .

Ví dụ: lấy một tập hợp tất cả các nút div trong document

const div_nodes = document.getElementsByTagName("div");

Nếu có hai phần tử div trong document , thì NodeList (giá trị của biến div_nodes ở đây) chứa hai nút. Nếu có ba phần tử, NodeList chứa ba phần tử

Chọn tất cả node <p> trong document : const myNodeList = document.querySelectorAll("p");

Các phần tử trong NodeList có thể được truy cập bằng một số chỉ mục. Để truy cập vào node <p> thứ 2 ta có thể viết myNodeList[1] (chỉ mục sẽ bắt đầu từ số 0)

<h2>JavaScript</h2>

<p>Hello World!</p>

<p>Lập Trình Từ Đầu!</p>

<p id="demo"></p>

<script>
const myNodelist = document.querySelectorAll("p");

document.getElementById("demo").innerHTML = "The innerHTML of the second paragraph is: " + myNodelist[1].innerHTML;

</script>

2. Thuộc tính length với NodeList

Thuộc tính length dùng để xác định số lượng node trong NodeList . Cú pháp của nó là:

numItems = nodeList.length

Trong đó numItems là một giá trị số nguyên đại diện cho số mục trong một NodeList

Ví dụ:

<h2>JavaScript</h2>

<p>Hellow World!</p>

<p>Lập Trình Từ Đầu!</p>

<p id="demo"></p>

<script>
const myNodelist = document.querySelectorAll("p");

document.getElementById("demo").innerHTML = "Tài liệu này chứa " + myNodelist.length + " đoạn văn.";

</script>

Thuộc tính length cũng rất hữu ích khi khi ta muốn lặp qua các node trong NodeList

<h2>JavaScript</h2>

<p>Hello World!</p>

<p>Lập Trình Từ Đầu!</p>

<p>Nhấp vào nút để thay đổi màu của tất cả các phần tử p.</p>

<button onclick="myFunction()">Try it</button>

<script>
function myFunction() {
  const myNodelist = document.querySelectorAll("p");
  for (let i = 0; i < myNodelist.length; i++) {
    myNodelist[i].style.color = "blue";
  }
}
</script>

3. Phương thức sử dụng với NodeList

3.1. NodeList.item

Phương thức này sẽ trả về một node từ một NodeList . Phương thức này sẽ không đưa ra các ngoại lệ miễn là ta cung cấp các đối số. Giá trị của null được trả về nếu chỉ mục nằm ngoài phạm vi và một TypeError được trả về nếu không có đối số nào được cung cấp.

Cú pháp : nodeItem = nodeList.item(index)

Ví dụ:

var tables = document.getElementsByTagName("table");
var firstTable = tables.item(1); // hoặc các bảng [1] - trả về bảng thứ hai trong DOM

3.2. NodeList.entries 

Phương thức NodeList.entries trả về một iterator cho phép đi qua tất cả cặp key/value có trong đối tượng này. Giá trị chính là các đối tượng node.

Ví dụ:

var node = document.createElement("div");
var kid1 = document.createElement("p");
var kid2 = document.createTextNode("hey");
var kid3 = document.createElement("span");
node.appendChild(kid1);
node.appendChild(kid2);
node.appendChild(kid3);

var list = node.childNodes;

// sử dụng for..of
for(var entry of list.entries()) {
  console.log(entry);
}

3.3. Vòng lặp forEach

Cho phép ta duyệt các đối tượng iterable . Phương thức forEach của NodeList gọi callback được cấp trong tham số của forEach cho mỗi cặp giá trị trong danh sách và theo thứ tự chèn.

Cú pháp : someNodeList.forEach(callback[, thisArg]);

Trong đó:

  • Callback : một hàm để thực thi trên mỗi phần tử của someNodeList với việc chấp nhận các tham số như: currentValue(phần tử hiện tại đang được xử lý trong someNodeList) và currentIndex (chỉ mục của đối tượng currentValue đang được xử lý trong someNodeList)
  • ThisArg : giá trị được sử dụng khi thực thi callback

Ví dụ:

let node = document.createElement("div");
let kid1 = document.createElement("p");
let kid2 = document.createTextNode("hey");
let kid3 = document.createElement("span");

node.appendChild(kid1);
node.appendChild(kid2);
node.appendChild(kid3);

let list = node.childNodes;

list.forEach(
  function(currentValue, currentIndex, listObj) {
    document.write(currentValue + ', ' + currentIndex + ', ' + this);
  },
  'myThisArg'
);

3.4. NodeList.keys() và NodeList.values​()

Phương thức NodeList.keys() trả về một iterator cho phép đi qua tất cả các key có trong đối tượng này

Ví dụ:

var node = document.createElement("div");
var kid1 = document.createElement("p");
var kid2 = document.createTextNode("hey");
var kid3 = document.createElement("span");

node.appendChild(kid1);
node.appendChild(kid2);
node.appendChild(kid3);

var list = node.childNodes;

// Using for..of
for(var key of list.keys()) {
   document.write(key);
}

Tương tự phương thức NodeList.values​() trả về một iterator cho phép đi qua tất cả value có trong đối tượng này

Ví dụ:

var node = document.createElement("div");
var kid1 = document.createElement("p");
var kid2 = document.createTextNode("hey");
var kid3 = document.createElement("span");

node.appendChild(kid1);
node.appendChild(kid2);
node.appendChild(kid3);

var list = node.childNodes;

// Using for..of
for(var value of list.values()) {
  document.write(value);
}

4. Sự Khác biệt giữa HTMLCollection và NodeList

Một HTMLCollection là một tập hợp các phần tử HTML. Một NodeList là một tập hợp các node tài liệu. Trong nhiều trường hợp, hai đối tượng này rất giống nhau.

Cả hai đối tượng HTMLCollectionNodeList là một danh sách giống như mảng (collection) các đối tượng. Cả hai đều có thuộc tính chiều dài xác định số lượng mục trong danh sách. Cả hai đều cung cấp một chỉ mục (0, 1, 2, 3, 4, …) để truy cập vào từng mục như một mảng. Nhưng:

  • Các mục HTMLCollection có thể được truy cập theo tên, id hoặc số thứ tự của chúng.
  • Các mục NodeList chỉ có thể được truy cập bởi số chỉ mục của chúng. Chỉ đối tượng NodeList có thể chứa các node thuộc tính và văn bản.

Một NodeList có vẻ trong giống như là một mảng vậy. Vì ta có thể lặp NodeList và xem các node của nó như là một mảng. Tuy nhiên, bạn không thể sử dụng phương thức mảng như valueOf() , push() , pop() , hoặc join() trên một danh sách node .