Thứ hai, 04/12/2017 | 00:00 GMT+7

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ượng document để 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.

node.html
<!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.

trang node.html

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 , pul , 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 , headbody 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 , pul 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 - parentNodeparentElement .

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ủa head , bodyscript .
  • body là cha của h1 , h2 , pul , nhưng không phải li , vì li là hai cấp so với body .

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 pbody , 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 , firstElementChildlastElementChild 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.

sửa đổi firstElementChild.style.background

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.

sửa đổi các yếu tố trẻ em

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."

childNodeschildren 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ửa đổi phần tử con cuối cùng

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ử. previousSiblingnextSibling 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à previousElementSiblingnextElementSibling 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 Hammerheadaquamarine cho nền của Great White .

sửa đổi yếu tố anh chị em

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.


Tags:

Các tin liên quan