how-to-traverse-the-dom
Hướng dẫn trước trong loạt bài này, Cách truy cập các phần tử trong DOM , trình bày cách sử dụng các phương thức tích hợp sẵn của đối tượngdocument
để truy cập các phần tử HTML theo ID, lớp, tên thẻ và bộ chọn truy vấn. Ta biết rằng DOM được cấu trúc như một cây gồm các node với nút document
ở root và mọi nút khác (bao gồm các phần tử, chú thích và các node văn bản) là các nhánh khác nhau. Thông thường, bạn cần di chuyển qua DOM mà không chỉ định trước từng phần tử. Học cách chuyển lên xuống cây DOM và di chuyển từ nhánh này sang nhánh khác là điều cần thiết để hiểu cách làm việc với JavaScript và HTML.
Trong hướng dẫn này, ta sẽ xem xét cách duyệt qua DOM ( còn gọi là đi bộ hoặc chuyển DOM) với các thuộc tính cha, con và anh chị em.
Cài đặt
Để bắt đầu, ta sẽ tạo một file mới có tên là nodes.html
bao gồm đoạn mã sau.
<!DOCTYPE html> <html> <head> <title>Learning About Nodes</title> <style> * { border: 2px solid #dedede; padding: 15px; margin: 15px; } html { margin: 0; padding: 0; } body { max-width: 600px; font-family: sans-serif; color: #333; } </style> </head> <body> <h1>Shark World</h1> <p>The world's leading source on <strong>shark</strong> related information.</p> <h2>Types of Sharks</h2> <ul> <li>Hammerhead</li> <li>Tiger</li> <li>Great White</li> </ul> </body> <script> const h1 = document.getElementsByTagName('h1')[0]; const p = document.getElementsByTagName('p')[0]; const ul = document.getElementsByTagName('ul')[0]; </script> </html>
Khi ta tải file trong trình duyệt web, ta sẽ thấy kết xuất giống như ảnh chụp màn hình sau.
Trong trang web ví dụ này, ta có một trang HTML với một vài phần tử. Một số CSS cơ bản đã được thêm vào thẻ style
để làm cho mỗi phần tử hiển thị rõ ràng và một vài biến đã được tạo trong script
để dễ dàng truy cập vào một số phần tử. Vì chỉ có một trong mỗi h1
, p
và ul
, ta có thể truy cập index đầu tiên trên mỗi thuộc tính getElementsByTagName
tương ứng.
Nút root
Đối tượng document
là root của mọi nút trong DOM. Đối tượng này thực sự là một thuộc tính của đối tượng window
, là đối tượng toàn cục, cấp cao nhất đại diện cho một tab trong trình duyệt. Đối tượng window
có quyền truy cập vào các thông tin như thanh công cụ, chiều cao và chiều rộng của cửa sổ, dấu nhắc và cảnh báo. document
bao gồm những gì bên trong window
bên trong.
Dưới đây là biểu đồ bao gồm các phần tử root mà mọi tài liệu sẽ chứa. Ngay cả khi một file HTML trống được tải vào trình duyệt, ba nút này sẽ được thêm và phân tích cú pháp thành DOM.
Bất động sản | Nút | Loại nút |
---|---|---|
document | #document | DOCUMENT_NODE |
document.documentElement | html | ELEMENT_NODE |
document.head | head | ELEMENT_NODE |
document.body | body | ELEMENT_NODE |
Vì các phần tử html
, head
và body
rất phổ biến nên chúng có các thuộc tính riêng trên document
.
Mở Control panel trong DevTools và kiểm tra từng thuộc tính trong số bốn thuộc tính này bằng cách gửi chúng và xem kết quả . Bạn cũng có thể kiểm tra h1
, p
và ul
sẽ trả về các phần tử do các biến ta đã thêm trong thẻ script
.
Nút mẹ
Các node trong DOM được gọi là cha mẹ, con cái và anh chị em, tùy thuộc vào mối quan hệ của chúng với các node khác. Nút cha của bất kỳ nút nào là nút cao hơn một cấp hoặc gần hơn với document
trong phân cấp DOM. Có hai thuộc tính để lấy cha - parentNode
và parentElement
.
Bất động sản | Được |
---|---|
parentNode | Nút cha |
parentElement | Nút phần tử cha |
Trong ví dụ về nodes.html
của ta :
-
html
là cha củahead
,body
vàscript
. -
body
là cha củah1
,h2
,p
vàul
, nhưng không phảili
, vìli
là hai cấp so vớibody
.
Ta có thể kiểm tra phần tử cha của phần tử p
của ta là gì bằng thuộc tính parentNode
. Biến p
này đến từ khai báo document.getElementsByTagName('p')[0]
tùy chỉnh của ta .
- p.parentNode;
Output► <body>...</body>
Cha của p
là body
, nhưng làm thế nào ta có thể lấy được grandparent, là hai cấp trên? Ta có thể thực hiện bằng cách xâu chuỗi các thuộc tính lại với nhau.
- p.parentNode.parentNode;
Output► <html>...</html>
Bằng cách sử dụng parentNode
hai lần, ta truy xuất hàm ông bà của p
.
Có các thuộc tính để truy xuất nút cha của một nút, nhưng chỉ có một sự khác biệt nhỏ giữa chúng, như được minh họa trong đoạn mã dưới đây.
- // Assign html object to html variable
- const html = document.documentElement;
-
- console.log(html.parentNode); // > #document
- console.log(html.parentElement); // > null
Phần tử cha của hầu hết mọi nút đều là một nút phần tử, vì văn bản và chú thích không thể là phần tử cha cho các node khác. Tuy nhiên, cha của html
là một nút tài liệu, do đó, parentElement
trả về null
. Nói chung, parentNode
thường được sử dụng hơn khi duyệt qua DOM.
Nút trẻ em
Các node con của một nút là các node thấp hơn nó một cấp. Bất kỳ nút nào vượt quá một mức lồng ghép thường được gọi là con cháu.
Bất động sản | Được |
---|---|
childNodes | Nút con |
firstChild | Nút con đầu tiên |
lastChild | Nút con cuối cùng |
children | Nút con nguyên tố |
firstElementChild | Nút phần tử con đầu tiên |
lastElementChild | Nút phần tử con cuối cùng |
Thuộc tính childNodes
sẽ trả về danh sách trực tiếp của mọi nút con. Bạn có thể mong đợi phần tử ul
nhận ba phần tử li
. Hãy kiểm tra những gì nó truy xuất.
- ul.childNodes;
Output► (7) [text, li, text, li, text, li, text]
Ngoài ba phần tử li
, nó còn có bốn nút văn bản. Điều này là do ta đã viết HTML của riêng mình (nó không được tạo bởi JavaScript) và thụt lề giữa các phần tử được tính trong DOM dưới dạng các node văn bản. Điều này không trực quan, vì tab Phần tử của DevTools loại bỏ các node khoảng trắng.
Nếu ta cố gắng thay đổi màu nền của nút con đầu tiên bằng thuộc tính firstChild
, nó sẽ không thành công vì nút đầu tiên là văn bản.
- ul.firstChild.style.background = 'yellow';
Output- Uncaught TypeError: Cannot set property 'background' of undefined
Các thuộc tính children
, firstElementChild
và lastElementChild
tồn tại trong các loại tình huống này để chỉ truy xuất các node phần tử. ul.children
sẽ chỉ trả về ba phần tử li
.
Sử dụng firstElementChild
, ta có thể thay đổi màu nền của chữ li
đầu tiên trong ul
.
- ul.firstElementChild.style.background = 'yellow';
Khi bạn chạy mã trên, trang web sẽ được cập nhật để sửa đổi màu nền.
Khi thực hiện thao tác DOM cơ bản như trong ví dụ này, các thuộc tính của phần tử cụ thể là cực kỳ hữu ích. Trong các ứng dụng web do JavaScript tạo, các thuộc tính chọn tất cả các node có nhiều khả năng được sử dụng hơn, vì các dòng mới và thụt lề sẽ không tồn tại trong trường hợp này.
Vòng lặp for...of
được dùng để lặp qua tất cả các phần tử children
.
- for (let element of ul.children) {
- element.style.background = 'yellow';
- }
Bây giờ, mỗi phần tử con sẽ có nền màu vàng.
Vì phần tử p
của ta có cả văn bản và các phần tử bên trong nó, thuộc tính childNodes
rất hữu ích để truy cập thông tin đó.
- for (let element of p.childNodes) {
- console.log(element);
- }
Output"The world's leading source on " <strong>shark</strong> " related information."
childNodes
và children
không trả về mảng với tất cả các thuộc tính và phương thức của Array , nhưng chúng xuất hiện và hoạt động tương tự như mảng JavaScript. Bạn có thể truy cập các node theo số index hoặc tìm thuộc tính length
của chúng.
- document.body.children[3].lastElementChild.style.background = 'fuchsia';
Đoạn mã trên sẽ tìm ra con yếu tố cuối cùng ( li
) của phần tử con thứ tư ( ul
) của body
và áp dụng một kiểu.
Sử dụng thuộc tính cha và con, bạn có thể truy xuất bất kỳ nút nào trong DOM.
Nút anh chị em
Anh chị em của một nút là bất kỳ nút nào trên cùng một cấp cây trong DOM. Các node anh chị em không nhất thiết phải là cùng một loại nút - văn bản, phần tử và các node chú thích đều có thể là anh chị em.
Bất động sản | Được |
---|---|
previousSibling | Nút anh chị em trước |
nextSibling | Nút anh chị em tiếp theo |
previousElementSibling | Nút phần tử anh chị em trước |
nextElementSibling | Nút phần tử anh chị em tiếp theo |
Các thuộc tính anh chị em hoạt động giống như các node con, trong đó có một tập hợp các thuộc tính để duyệt qua tất cả các node và một tập các thuộc tính chỉ cho các node phần tử. previousSibling
và nextSibling
sẽ nhận được các node tiếp theo mà ngay lập tức đến trước hoặc sau các node chỉ định, và previousElementSibling
và nextElementSibling
sẽ chỉ nhận được các node phần tử.
Trong ví dụ về nodes.html
của ta , hãy chọn phần tử ở giữa của ul
.
- const tiger = ul.children[1];
Vì ta đã tạo DOM từ đầu và không phải là một ứng dụng web JavaScript, ta cần sử dụng các thuộc tính anh em của phần tử để truy cập vào các node phần tử trước đó và tiếp theo, vì có khoảng trắng trong DOM.
- tiger.nextElementSibling.style.background = 'coral';
- tiger.previousElementSibling.style.background = 'aquamarine';
Chạy mã này nên áp dụng coral
cho nền của Hammerhead
và aquamarine
cho nền của Great White
.
Các thuộc tính anh chị em có thể được xâu chuỗi với nhau, giống như các thuộc tính cha và nút.
Kết luận
Trong hướng dẫn này, ta đã trình bày cách truy cập vào các node root của mọi trang HTML và cách dẫn cây DOM thông qua các thuộc tính cha, con và anh chị em.
Với những gì bạn đã học trong Cách truy cập các phần tử trong DOM và hướng dẫn này, bạn có thể tự tin truy cập vào bất kỳ nút nào trong DOM của bất kỳ trang web nào.
Các tin liên quan