TABLE OF CONTENTS

Hi 🤓 Cảm ơn bạn đã ghé thăm blog này, nếu những bài viết trên blog giúp ích cho bạn. Bạn có thể giúp blog hiển thị quảng cáo bằng cách tạm ngừng ad blocker 😫 và để giúp blog duy trì hoạt động nếu bạn muốn.
Cảm ơn bạn!

Khi sử dụng method querySelectorAll(), chúng ta nhận được một NodeList. Ngược lại, với getElementsByTagName() chúng ta sẽ lấy được HTMLCollection. Trong bài viết này, chúng ta sẽ cùng so sánh NodeList vs HTMLCollection trong JavaScript nhé 😁.

NodeList vs HTMLCollection

Để so sánh NodeList vs HTMLCollection, mình xin đưa ra một ví dụ sau:

<div id="content">
  <a href="https://homiedev.com/hoc-javascript-co-ban/">Học JavaScript cơ bản</a>
  <a href="https://homiedev.com/javascript-projects-for-beginners/">100+ JavaScript Projects</a>
</div>

Tiếp theo sử dụng JavaScript, chúng ta có thể lấy tất cả thẻ a của div#content bằng cách:

// lấy tất cả thẻ a sử dụng querySelectorAll hoặc getElementsByTagName
const elements1 = document.querySelectorAll("a");
const elements2 = document.getElementsByTagName("a");

console.log(
  "querySelectorAll",
  elements1,
  "getElementsByTagName",
  elements2
);

Kết quả chúng ta được:

NodeList vs HTMLCollection example

Chúng ta có thể sử dụng getElementsByClassName() hoặc getElementsByTagName(), kết quả sẽ trả về một HTMLCollection. Sử dụng querySelectorAll() hoặc getElementsByName() nếu muốn kết quả là một NodeList.

Đầu tiên, chúng ta có thể nói về điểm giống nhau giữa NodeList và HTMLCollection đó chính là cả hai đều là array-like object, chúng nhìn rất giống mảng nhưng thực chất không phải là mảng.

Array-like là một object, đặc biệt ở chỗ nó có thuộc tính length và những thuộc tính với key là số nguyên, vì lý do đó chúng nhìn rất giống với mảng trong JavaScript.

Để hiểu rõ hơn về array-like object trong JavaScript, bạn có thể đọc bài viết: Array-like Object trong JavaScript là gì? Tại sao bạn cần nên biết.

Vì lý do lầm tưởng là mảng, nên nhiều bạn sử dụng method của mảng để lặp qua, ví dụ:

const elements = document.getElementsByTagName("a"); // HTMLCollection

elements.forEach(element => {
  console.log(element);
});

// lỗi: elements.forEach is not a function

Lỗi sẽ xảy ra vì kết quả nhận được từ getElementsByTagName() là một HTMLCollection và nó là một array-like object. Chúng ta có thể lặp bằng cách chuyển nó sang mảng sử dụng Array.from() hoặc spread operator:

const elements = document.getElementsByTagName("a"); // HTMLCollection

const array = Array.from(elements);

array.forEach((element) => {
  console.log(element);
});
// OK

Với NodeList, nếu các bạn nhìn vào hình trên sẽ thấy nó có method là forEach(), nên chúng ta có thể lặp qua các phần tử nếu muốn:

const elements = document.querySelectorAll("a"); // NodeList

elements.forEach(element => {
  console.log(element);
});
// OK

Ở trên là điểm khác biệt đầu tiên giữa NodeList và HTMLCollection chúng ta có thể nhận thấy.

Điểm khác biệt tiếp theo có thể kể đến là sử dụng NodeList để lấy phần tử theo ý muốn thì chúng ta sẽ sử dụng index:

const elements = document.querySelectorAll("a"); // NodeList

// cách truy xuất nhìn rất giống mảng
// tuy nhiên elements là một array-like 
console.log(elements[0]);

Với HTMLCollection, nhìn vào hình trên, chúng ta có thể thấy nó có một method tên là namedItem(), method này sử dụng name hoặc id để lấy phần tử theo ý muốn và trả null nếu không tìm thấy.

Như vậy ta có thể sử dụng name, id hoặc index để lấy phần tử theo ý muốn khi sử dụng HTMLCollection.

<div id="content">
  Homiedev.com
  <a name="link_1" id="link_id1" href="https://homiedev.com/hoc-javascript-co-ban/">Học JavaScript cơ bản</a>
  <a href="https://homiedev.com/javascript-projects-for-beginners/">100+ JavaScript Projects</a>
</div>
const elements = document.getElementsByTagName("a"); // HTMLCollection

console.log(elements[0]); // sử dụng index
console.log(elements.namedItem("link_id1")); // get bằng id
console.log(elements.namedItem("link_1")); // get bằng name

Điểm khác biệt tiếp theo đó là khi thao tác DOM, những thay đổi có liên quan được update cho HTMLCollection (live), với NodeList (sử dụng querySelectorAll()) những thay đổi này sẽ không được update (static).

const elements1 = document.querySelectorAll("a"); // static
const elements2 = document.getElementsByTagName("a"); // live
const content = document.getElementById("content");

// thêm một phần tử vào `div#content`
content.appendChild(document.createElement("a"));

console.log(elements1.length); // 2
console.log(elements2.length); // 3

NodeList có 2 loại Live NodeList và Static NodeList. Sử dụng querySelectorAll() ta sẽ nhận được Static NodeList. Trường hợp là Live NodeList ví dụ Node.childNodes.

const parent = document.getElementById('homiedev');
let childNodes = parent.childNodes; // NodeList

console.log(childNodes.length); // 2
parent.appendChild(document.createElement('div'));
console.log(childNodes.length); // 3

Hi vọng bài viết giúp ích cho các bạn. Đừng quên theo dõi blog và đăng ký kênh youtube homiedev để theo dõi những nội dung về Frontend nhé ^^. Chúc các bạn học tốt.

Có thể bạn thích ⚡
homiedev
About Me

Hi, I'm @devnav. Một người thích chia sẻ kiến thức, đặc biệt là về Frontend 🚀. Trang web này được tạo ra nhằm giúp các bạn học Frontend hiệu quả hơn 🎉😄.

Chúc các bạn tìm được kiến thức hữu ích trong blog này 😁😁.