Kiến thức lập trình

Điều hướng DOM trong JavaScript

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

 

Điều hướng giữa các DOM node là gì?

 

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

 

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

 

Cách truy cập các Node con

 

Bạn có thể sử dụng thuộc tính firstChildlastChild 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 firstChildlastChild trả về #text hoặc #comment?

 

Để tránh như thế, bạn có thể sử dụng các thuộc tính firstElementChildlastElementChild để 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>

 

Cách truy cập các node cha

 

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.

 

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>

 

Cách truy cập các Node anh chị em

 

Bạn có thể sử dụng các thuộc tính previousSiblingnextSibling để 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 previousElementSiblingnextElementSibling để 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ó.

 

Có mấy kiểu DOM node?

 

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

Tags