Tác giả NIIT - ICT HANOI
Ngày đăng 08/ 08/ 2020
Bình luận 0 Bình luận
Trong hướng dẫn tự học JavaScript này, bạn sẽ học cách điều hướng giữa các DOM node trong JavaScript.
Trong các bài học trước, bạn đã học cách chọn sử dụng JS để truy cập các phần tử riêng lẻ trên một trang web.
Nhưng có nhiều trường hợp bạn cần nhắm đến phần tử con, cha mẹ hoặc tổ tiên của phần tử được chọn thì làm thế nào?
Trong bài này, chúng ta sẽ được học về điều hướng DOM trong JavaScript
Điều hướng DOM trong JavaScript
Lưu ý: Nên xem bài DOM là gì để hiểu mối quan hệ logic giữa các node trong DOM tree.
Bạn có thể sử dụng thuộc tính firstChild và lastChild của DOM node để truy cập node con trực tiếp đầu tiên và node con cuối cùng.
Nếu node bạn đang nhắm đến không có bất kỳ phần tử con nào, nó sẽ trả về null.
Ví dụ, chúng ta có HTML:
<div id="main">
<h1 id="tieuDe">Cách truy cập Node con</h1>
<p id="moTa"><span>Đây là một đoạn text.</span></p>
</div>
JavaScript:
<script>
var main = document.getElementById("main");
console.log(main.firstChild.nodeName); // Kết quả: #text
var moTa = document.getElementById("moTa");
console.log(moTa.firstChild.nodeName); // Kết quả: SPAN
</script>
Lưu ý: nodeName là thuộc tính chỉ đọc trả về tên của node hiện tại dưới dạng một chuỗi. (Ví dụ: nó trả về tên thẻ cho các node là phần tử, #text cho node văn bản, #comment cho node nhận xét, #document cho node document, v.v. )
Nếu bạn nhận thấy ví dụ trên, nodeName của node con đầu tiên của phần tử DIV chính trả về là #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 node #text và trở thành một phần của DOM tree.
Do đó, vì thẻ div chứa một dòng mới trước thẻ h1, vì vậy nó sẽ tạo một node #text.
Vậy, làm thến nào để tránh sự cố với các node firstChild và lastChild trả về #text hoặc #comment?
Để tránh như thế, bạn có thể sử dụng các thuộc tính firstElementChild và lastElementChild để chỉ trả về node là 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.
Tại vẫn sử dụng HTML ở trên nhé.
Và đây là JavaScript đã chỉnh lại:
<script>
var main = document.getElementById("main");
console.log(main.firstElementChild.nodeName); // Kết quả: H1
main.firstElementChild.style.color = "red";
var moTa = document.getElementById("moTa");
console.log(moTa.lastElementChild.nodeName); // Kết quả: SPAN
moTa.lastElementChild.style.color = "blue";
</script>
Tương tự, bạn có thể sử dụng thuộc tính childNodes để truy cập tất cả các node con của một phần tử nhất định.
Trong đó node con đầu tiên được gán chỉ mục là 0.
Hãy cùng làm ví dụ sau:
Vẫn sử dụng HTML ở trên nha:
<div id="main">
<h1 id="tieuDe">Cách truy cập Node con</h1>
<p id="moTa"><span>Đây là một đoạn text.</span></p>
</div>
Đây là JavaScript:
<script>
var main = document.getElementById("main");
// Đầu tiên, ta kiểm tra xem Node này có phần tử con hay không
if (main.hasChildNodes()) {
var nodes = main.childNodes;
// Lặp qua các phần tử trong số node được trả về và in tên node đó
for (var i = 0; i < nodes.length; i++) {
alert(nodes[i].nodeName);
}
}
</script>
Lưu ý rằng childNodes về tất cả các node con, bao gồm cả các node non-element (như node văn bản và node nhận xét).
Để có được một tập hợp chỉ gồm các phần tử, hãy sử dụng thuộc tính children thay thế.
Vẫn sử dụng HTML trên nha.
Và đây là JavaScript:
<script>
var main = document.getElementById("main");
// Đầu tiên, kiểm ra xem phần tử đang nhắm đến có phần tử con hay không
if (main.hasChildNode()) {
var nodes = main.children;
// Lặp qua các node element trả về và thông báo tên của nó
for (var i = 0; i < nodes.length; i++) {
alert(nodes[i].nodeName);
}
}
</script>
Bạn có thể sử dụng thuộc tính parentNode để truy cập nút cha của nút được chỉ định trong cây DOM.
Và parentNode sẽ luôn trả về null cho node document, vì nó không có cha.
Hãy xem ví dụ sau đây:
HTML:
<div id="main">
<h1 id="tieuDe">Cách truy cập Node cha</h1>
<p id="moTa"><span>Đây là một đoạn text.</span></p>
</div>
JavaScript:
<script>
var moTa = document.getElementById(moTa);
console.log(moTa.parentNode.nodeName); // Kết quả: DIV
console.log(document.documentElement.parentNode.nodeNam); // #document
console.log(document.parentNode); // null
</script>
Mẹo: Các DOM tree node trên cùng có thể được truy cập trực tiếp 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
+ 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 nhận các node element, bạn có thể sử dụng parentElement, như sau:
<script>
var moTa = document.getElementById("moTa");
console.log(moTa.parentElement.nodeName); // DIV
moTa.parentElement.style.backgroundColor = "blue";
</script>
Bạn có thể sử dụng các thuộc tính previousSibling và nextSibling để truy cập node trước đó và node ngay sau theo trong DOM tree tương ứng. Đây là một ví dụ:
HTML:
<div id="main">
<h1 id="tieuDe">Cách truy cập Node anh chị em</h1><br />
<p id="moTa"><span>Đây là một đoạn text.</span></p>
</div>
JavaScript:
<script>
var moTa = document.getElementById("moTa");
console.log(moTa.previousSibling.nodeName); // #text
var tieuDe = document.getElementById("tieuDe");
console.log(tieuDe.nextSibling.nodeName); // BR
</script>
Ngoài ra, bạn có thể sử dụng previousElementSibling và nextElementSibling để lấy phần tử anh em trước đó và tiếp theo bỏ qua bất kỳ node 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ó anh chị em nào như thế. Đây là một ví dụ:
HTML:
<div id="main">
<h1 id="tieuDe">Cách truy cập Node anh chị em</h1>
<p id="moTa"><span>Đây là một đoạn text.</span></p>
</div>
JavaScript:
<script>
var moTa = document.getElementById("moTa");
console.log(moTa.previousElementSibling.nodeName);
console.log(moTa.previousElementSibling.textContent);
var tieuDe = document.getElementById("tieuDe");
console.log(tieuDe.nextElementSibling.nodeName);
console.log(tieuDe.nextElementSibling.textContent);
</script>
Hãy thử chạy trên trình duyệt và kiểm tra bảng điều khiển Console xem thế nào nhé.
Thuộc tính textContent đại diện cho nội dung văn bản của một node và tất cả các node con của nó.
Hãy xem bài viết thao tác với DOM trong JavaScript để tìm hiểu thêm về nó.
DOM tree bao gồm các loại node khác nhau, chẳng hạn như:
+ Phần tử
+ Văn bản
+ Nhận xét
+ ...
Mỗi node đều có thuộc tính nodeType mà bạn có thể sử dụng để tìm ra loại node bạn đang xử lý.
Bảng bên dưới đây liệt kê các loại node quan trọng nhất:
# | Giá trị | Mô tả |
---|---|---|
ELEMENT_NODE |
1 | Một node element như <p> hoặc <img> . |
TEXT_NODE |
3 | Văn bản thực tế cảu phần tử |
COMMENT_NODE |
8 | Một node nhận xét, VD: <!-- Nhận xét --> |
DOCUMENT_NODE |
9 | Một document node tức là cha của <html> |
DOCUMENT_TYPE_NODE |
10 | Một kiểu document node, VD <!DOCTYPE html> cho HTML5 |
Như vậy, bài viết này mình vừa giúp bạn tìm hiểu thêm về cách điều hướng DOM trong JavaScript.
Bạn đã biết cách truy cập các node con, node cha và node anh chị em như thế nào.
Hi vọng bạn hiểu được nó, nếu chưa, hãy tự làm lại ví dụ trong bài vài lần nha. Vì học lập trình là phải thực hành, càng nhiều càng tốt.
Đọc thêm: Get và Set thuộc tính thông qua JS DOM