Đ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à lastChild
củ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 previousSibling
và 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ề null
nế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. |