JavaScript cơ bản
JavaScript & DOM
JavaScript & BOM
JavaScript nâng cao
Quảng cáo

Điều hướng JS DOM

Trong hướng dẫn này, bạn sẽ tìm hiểu cách điều hướng giữa các nút DOM trong JavaScript.

Điều hướng giữa các nút DOM

Trong các chương trước bạn đã học cách chọn các thành phần riêng lẻ trên một trang web. Nhưng có nhiều trường hợp bạn cần truy cập vào phần tử con, cha mẹ hoặc tổ tiên. Xem chương nút JavaScript DOM để hiểu mối quan hệ logic giữa các nút trong cây DOM.

Nút DOM cung cấp một số thuộc tính và phương thức cho phép bạn điều hướng hoặc duyệt qua cấu trúc cây của DOM và thực hiện các thay đổi rất dễ dàng. Trong phần sau, chúng ta sẽ tìm hiểu cách điều hướng lên, xuống và sang một bên trong cây DOM bằng JavaScript.

Truy cập các nút con

Bạn có thể sử dụng các thuộc tính firstChild và lastChildcủa nút DOM để truy cập nút con trực tiếp đầu tiên và cuối cùng của nút tương ứng. Nếu nút không có bất kỳ phần tử con nào, nó sẽ trả về null.

Ví dụ

<div id="main">
    <h1 id="title">My Heading</h1>
    <p id="hint"><span>This is some text.</span></p>
</div>

<script>
let main = document.getElementById("main");
console.log(main.firstChild.nodeName); // Prints: #text

let hint = document.getElementById("hint");
console.log(hint.firstChild.nodeName); // Prints: SPAN
</script>
 

Lưu ý: Thuộc tính nodeName chỉ đọc trả về tên của nút hiện tại dưới dạng chuỗi. Ví dụ: nó trả về tên thẻ cho nút phần tử, #text cho nút văn bản, #comment cho nút nhận xét, #document cho nút tài liệu, v.v.

Nếu bạn chú ý đến ví dụ trên, nodeName nút con đầu tiên của phần tử DIV chính sẽ trả về #text thay vì H1. Bởi vì, các khoảng trắng như dấu cách, tab, dòng mới, v.v. là các ký tự hợp lệ và chúng tạo thành các nút #text và trở thành một phần của cây DOM. Do đó, vì thẻ <div> chứa một dòng mới trước thẻ<h1> nên nó sẽ tạo nút #text.

Để tránh sự cố với firstChild và lastChild trả về các nút #text hoặc #comment, bạn có thể sử dụng các thuộc tính firstElementChild và lastElementChild để chỉ trả về nút phần tử đầu tiên và cuối cùng tương ứng. Tuy nhiên, nó sẽ không hoạt động trong IE 9 trở về trước.

Ví dụ

<div id="main">
    <h1 id="title">My Heading</h1>
    <p id="hint"><span>This is some text.</span></p>
</div>

<script>
let main = document.getElementById("main");
alert(main.firstElementChild.nodeName); // Outputs: H1
main.firstElementChild.style.color = "red";

let hint = document.getElementById("hint");
alert(hint.firstElementChild.nodeName); // Outputs: SPAN
hint.firstElementChild.style.color = "blue";
</script>

Tương tự, bạn có thể sử dụng thuộc tínhchildNodes này để truy cập tất cả các nút con của một phần tử nhất định, trong đó nút con đầu tiên được gán chỉ mục 0. Dưới đây là một ví dụ:

Ví dụ

<div id="main">
    <h1 id="title">My Heading</h1>
    <p id="hint"><span>This is some text.</span></p>
</div>

<script>
let main = document.getElementById("main");

// First check that the element has child nodes 
if(main.hasChildNodes()) {
    let nodes = main.childNodes;
    
    // Loop through node list and display node name
    for(let i = 0; i < nodes.length; i++) {
        alert(nodes[i].nodeName);
    }
}
</script>

childNodes trả về tất cả các nút con, bao gồm các nút không phải phần tử như nút văn bản và nút nhận xét. Để có được một tập hợp chỉ có các phần tử, children thay vào đó hãy sử dụng thuộc tính.

Ví dụ

<div id="main">
    <h1 id="title">My Heading</h1>
    <p id="hint"><span>This is some text.</span></p>
</div>

<script>
let main = document.getElementById("main");

// First check that the element has child nodes 
if(main.hasChildNodes()) {
    let nodes = main.children;
    
    // Loop through node list and display node name
    for(let i = 0; i < nodes.length; i++) {
        alert(nodes[i].nodeName);
    }
}
</script>

Truy cập các nút gốc

Bạn có thể sử dụng thuộc tính parentNode này để truy cập nút cha của nút được chỉ định trong cây DOM.

parentNode sẽ luôn trả null về nút tài liệu vì nó không có nút gốc.

Ví dụ

<div id="main">
    <h1 id="title">My Heading</h1>
    <p id="hint"><span>This is some text.</span></p>
</div>

<script>
let hint = document.getElementById("hint");
alert(hint.parentNode.nodeName); // Outputs: DIV
alert(document.documentElement.parentNode.nodeName); // Outputs: #document
alert(document.parentNode); // Outputs: null
</script>
 

Mẹo: Bạn có thể truy cập trực tiếp các nút cây DOM trên cùng dưới dạng thuộc tính document. Ví dụ: phần tử <html> có thể được truy cập bằng thuộc tính document.documentElement, trong khi phần tử <head> có thể được truy cập bằng thuộc tính document.head và phần tử <body> có thể được truy cập bằng thuộc tính document.body.

Tuy nhiên, nếu bạn chỉ muốn lấy các nút phần tử, bạn có thể sử dụng parentElement, như thế này:

Ví dụ

<div id="main">
    <h1 id="title">My Heading</h1>
    <p id="hint"><span>This is some text.</span></p>
</div>

<script>
let hint = document.getElementById("hint");
alert(hint.parentNode.nodeName); // Outputs: DIV
hint.parentNode.style.backgroundColor = "yellow";
</script>

Truy cập các nút trước và tiếp

Bạn có thể sử dụng các thuộc tính previousSiblingvà nextSiblingđể truy cập nút trước và nút tiếp theo trong cây DOM tương ứng. Đây là một ví dụ:

Ví dụ

<div id="main">
    <h1 id="title">My Heading</h1>
    <p id="hint"><span>This is some text.</span></p><hr>
</div>

<script>
let title = document.getElementById("title");
alert(title.previousSibling.nodeName); // Outputs: #text

let hint = document.getElementById("hint");
alert(hint.nextSibling.nodeName); // Outputs: HR
</script>

Ngoài ra, bạn có thể sử dụng previousElementSibling và nextElementSibling để lấy phần tử trước và tiếp theo bỏ qua bất kỳ nút văn bản khoảng trắng nào. Tất cả các thuộc tính này trả về nullnếu không có phần tử như vậy. Đây là một ví dụ:

Ví dụ

<div id="main">
    <h1 id="title">My Heading</h1>
    <p id="hint"><span>This is some text.</span></p>
</div>

<script>
let hint = document.getElementById("hint");
alert(hint.previousElementSibling.nodeName); // Outputs: H1
alert(hint.previousElementSibling.textContent); // Outputs: My Heading

let title = document.getElementById("title");
alert(title.nextElementSibling.nodeName); // Outputs: P
alert(title.nextElementSibling.textContent); // Outputs: This is some text.
</script>

Thuộc tính textContent đại diện cho nội dung văn bản của một nút và tất cả các nút con của nó. Xem chương thao tác DOM JavaScript để tìm hiểu thêm về nó.

Các loại nút DOM

Cây DOM bao gồm các loại nút khác nhau, chẳng hạn như phần tử, văn bản, nhận xét, v.v.

Mỗi nút có một thuộc tính nodeType mà bạn có thể sử dụng để tìm ra loại nút bạn đang xử lý. Bảng sau liệt kê các loại nút quan trọng nhất:

Không thay đổi Giá trị Sự miêu tả
ELEMENT_NODE 1 Một nút phần tử chẳng hạn như <p>hoặc <img>.
TEXT_NODE 3 Văn bản thực tế của phần tử.
COMMENT_NODE số 8 Một nút bình luận tức là<!-- some comment -->
DOCUMENT_NODE 9 Một nút tài liệu tức là cha mẹ của <html>phần tử.
DOCUMENT_TYPE_NODE 10 Nút loại tài liệu, ví dụ như <!DOCTYPE html>đối với tài liệu HTML5.

Bài viết này đã giúp ích cho bạn?

Advertisements