JavaScript - DOM Nodes trong Javascript

by My Love

25/03/2019, 5:07 PM   |    26/03/2019, 2:55 PM   |    1.1K   |    0

      Các bạn đã được giới thiệu qua về DOM là gì rồi, bài này mình muốn nói sâu hơn một chút về Nodes nhé. Trong HTML DOM mọi thành phần đều được xem là một node, được biểu diễn trên một cấu trúc dạng cây gọi là DOM tree, trong đó có 3 loại quan trọng :
    - document node : là tài liệu HTML, được thể hiện bởi thẻ <html>
    - element node : đại diệu cho một phần tử HTML ( <head></head>, <title></title>, <a></a>, <p> ...)
    - text node : là các đoạn kí tự, đoạn text trong HTML ( ví dụ một đoạn văn bản trong một thẻ )
    -  Ngoài 3 loại trên còn có các thuộc tính ( attribute node ) và các chú thích ( comment node ).
Mô tả một cây DOM:
<!DOCTYPE html>
<html>
    <head>
        <title></title>
    </head>
    <body>
      <h1>chào bạn đến với vnfree.net</h1>
      <a>vnfree.net</a>
    </body>
</html>
      Vậy thì cơ bản bạn chỉ cần hiểu mỗi khi ta lấy một đối tượng nào đó bằng cách sử dụng DOM Element, ta gọi nó là một nodes. Bây giờ ta sẽ tìm hiểu cách sử dụng và một số phương thức của DOM Nodes.
1. Thêm mới HTML Elements
Ví dụ : Tạo mới một thẻ <p> sau đó thêm nội dung cho thẻ <p>, cuối cùng là gán thẻ <p> đó vào trong thẻ <div>
<html>
    <head>
        <title></title>
    </head>
    <body>
      <div id="DivId">
          <p>Chelsea</p>
          <p>Manchester UTD</p>
      </div>
      <script>
          // tạo mới một thẻ p
          var NewP = document.createElement("p");
          // tạo text node
          var node = document.createTextNode("Arsenal");
          // thêm nội dung vào thẻ p
          NewP.appendChild(node);
          
          var element = document.getElementById("DivId");
          // thêm thẻ p vào div
          element.appendChild(NewP);
      </script>
    </body>
</html>
Ở ví dụ trên :
    - Phương thức  createElement() giúp tạo một thẻ HTML, ta truyền vào tên thẻ cần tạo.
// tạo mới một thẻ p
var NewP = document.createElement("p");
    - Phương thức createTextNode() là tạo một text node - một nội dung dạng text cho thẻ
// tạo text node
var node = document.createTextNode("Arsenal");
    - Phương thức appendChild() có tác dụng thêm vào vị trí cuối cùng của thành phần. Như ví dụ trên node sẽ được thêm vào cuối cùng của thành phần NewP
// node được thêm vào vị trí cuối cùng của NewP
NewP.appendChild(node);
2. Một số phương thức khác của DOM Nodes
      Ngoài một số phương thức ở phần trên, ta hay sử dụng một số phương thức sau trong DOM Nodes :
Phương thức removeChild()
      Ngược lại với appendChild() phương thức removeChild() dùng để xóa một node con ra khỏi node hiện tại :
Ví dụ :
<html>
    <body>
        <div id="content">
            <p>Chelsea</p>
            <p>Manchester UTD</p>
            <p>Arsenal</p>
          </div>
       
        <input type="button" value="Xóa Nodes" id="remove"/>
       
        <script language="javascript">
            // Lấy button
            var button = document.getElementById("remove");

            // Thêm sự kiện click cho button
            button.addEventListener("click", function(){
             
            // Lấy thẻ cần remove
            var Node_name = document.querySelector("div p");
             
            // xóa node đầu tiên
            document.getElementById("content").removeChild(Node_name);
              
          	});
        </script>
    </body>
</html>
Phương thức replaceChild()
      Dùng để thay thế một node nào đó bằng một node mới
Ví dụ :
<html>
    <body>
        <div id="content">
            <p>Chelsea</p>
            <p>Manchester UTD</p>
            <p>Arsenal</p>
          </div>
       
        <input type="button" value="Thay thế Nodes" id="edit"/>
       
        <script language="javascript">
            // Lấy button
            var button = document.getElementById("edit");

            // Thêm sự kiện click cho button
            button.addEventListener("click", function(){
              
            // Tạo một node mới
            var newNode = document.createElement("p");
            // thêm nội dung cho thẻ p mới tạo
            // có thể dùng innerHTML để thêm thay vì createTextNode
            newNode.innerHTML = "Manchester City";
             
            // Lấy thẻ cần edit, ở đây là thẻ p đầu tiên
            var Node_name = document.querySelector("div p");
             
            // thay thê node đầu tiên bằng node mới
            document.getElementById("content").replaceChild(newNode, Node_name);
             
            // đưa ra thông báo
            alert("Bạn đã thay thế " + Node_name.innerHTML + " Bằng : " + newNode.innerHTML);
              
          	});
        </script>
    </body>
</html>
Phương thức insertBefore()
     Dùng để thêm một node vào đằng trước một node nào đó.
<html>
    <body>
        <div id="content">
            <p>Chelsea</p>
            <p>Manchester UTD</p>
            <p>Arsenal</p>
          </div>
       
        <input type="button" value="insertBefore Nodes" id="edit"/>
       
        <script language="javascript">
            // Lấy button
            var button = document.getElementById("edit");

            // Thêm sự kiện click cho button
            button.addEventListener("click", function(){
              
            // Tạo một node mới
            var newNode = document.createElement("p");
            // thêm nội dung cho thẻ p mới tạo
            // có thể dùng innerHTML để thêm thay vì createTextNode
            newNode.innerHTML = "Manchester City";
             
            // Lấy thẻ cần đưa node mới lên trước, ở đây là node thứ 3
            // mình sẽ đưa Manchester City lên trước Arsenal
            var Node_name = document.querySelectorAll("div p")[2];
             
            // thêm node mới lên trước node cần insertBefore
            document.getElementById("content").insertBefore(newNode, Node_name);
             
            // đưa ra thông báo
            alert("Bạn đã thêm " + newNode.innerHTML + " lên trước : " + Node_name.innerHTML);
              
          	});
        </script>
    </body>
</html>
3. Một số thuộc tính quan hệ
     
Bạn có thể sử dụng một số thuộc tính ở bảng dưới đây để lấy các nodes trong tài liệu :
Name Mô tả
parentNode Tham chiếu đến node cha hiện tại
childNodes[number] Tham chiếu đến các node con trực tiếp của node hiện tại
firstChild Tham chiếu đến node con đầu tiên của node hiện tại
lastChild Tham chiếu đến node con cuối cùng của node hiện tại
nextSibling Tham chiếu đến node anh em nằm liền kề sau với node hiện tại
previousSibling Tham chiếu đến node anh em nằm liền kề trước node hiện tại

Chú ý : Các thuộc tính bảng trên sẽ trả về các phần tử ( element node ) , các văn bản ( text node ) hoặc các chú thích ( comment node ). Trong nhiều trường hợp bạn chỉ  muốn lấy các phần tử ( element node ) mà bỏ qua các văn bản hay chú thích thì sử dụng các thuộc tính sau :
    - parentElement
    - children
    - firstElementChild
    - lastElementChild
    - nextElementSibling
    - previousElementSibling
Ví dụ : firstChild các thuộc tính khác bạn làm tương tự nhé
<html>
    <body>
        <div id="content">
            <p>Chelsea</p>
            <p>Manchester UTD</p>
            <p>Arsenal</p>
          </div>
       
        <input type="button" value="Get Nodes" id="edit"/>
       
        <script language="javascript">
            // Lấy button
            var button = document.getElementById("edit");

            // Thêm sự kiện click cho button
            button.addEventListener("click", function(){
              
            // Lấy node con đầu tiên của node hiện tại
            var Node_name = document.getElementById("content").firstChild;
              
            // đưa ra kết quả trống 
            // vì giữa thẻ div và thẻ <p> đầu tiên là kí tự xuống dòng \n
            alert(Node_name.nodeValue);
              
          	});
        </script>
    </body>
</html>
 Ví dụ trên mình dùng firstChild để lấy node con đầu tiên của node có id="content" (thẻ div). Sau đó dùng nodeValue để lấy giá trị của nó. Vì giữa thẻ div và thẻ <p> đầu tiên là kí tự xuống dòng "\n" nên đó chính là node firstChild lấy được, và kết quả in ra \n ( trống )
     Tương tự như trên nhưng bây giờ bạn cho thêm đoạn chú thích vào, và nó sẽ in ra đoạn chú thích :
<html>
    <body>
        <div id="content"><!-- Đây là chú thích -->
            <p>Chelsea</p>
            <p>Manchester UTD</p>
            <p>Arsenal</p>
          </div>
       
        <input type="button" value="Get Nodes" id="edit"/>
       
        <script language="javascript">
            // Lấy button
            var button = document.getElementById("edit");

            // Thêm sự kiện click cho button
            button.addEventListener("click", function(){
              
            // Lấy node con đầu tiên của node hiện tại
            var Node_name = document.getElementById("content").firstChild;
              
            // đưa ra kết quả là đoạn chú thích
            alert(Node_name.nodeValue);
              
          	});
        </script>
    </body>
</html>
Ok, bây giờ thay vì sử dụng firstChild, bạn sẽ sử dụng firstElementChild để xem khác gì nhé :
Ví dụ :
<html>
    <body>
        <div id="content"><!-- Đây là chú thích -->
            <p>Chelsea</p>
            <p>Manchester UTD</p>
            <p>Arsenal</p>
          </div>
       
        <input type="button" value="Get Nodes" id="edit"/>
       
        <script language="javascript">
            // Lấy button
            var button = document.getElementById("edit");

            // Thêm sự kiện click cho button
            button.addEventListener("click", function(){
              
            // Lấy node con đầu tiên của node hiện tại
            var Node_name = document.getElementById("content").firstElementChild;
              
            // đưa ra kết quả là nội dung của thẻ <p> đầu tiên
            alert(Node_name.innerHTML);
              
          	});
        </script>
    </body>
</html>
firstElementChild sẽ lấy về một thẻ HTML hay một đối tượng ( element node ) mà bỏ qua các text node hay comment node. Và nhớ là khi lấy về một đối đượng HTML rồi thì dùng innerHTML để lấy kiết quả thay vì nodeValue nhé.
4. Thuộc tính của một nodes
Thuộc tính nodeName :
      Khi ta lấy thuộc tính nodeName nó sẽ trả về tên của một nodes, có đặc điểm sau :
      - nodeName của một tài liệu ( document node ) sẽ trả về #document
      - nodeName của một phần tử ( element node ) sẽ trả về tên thẻ ( ví dụ : H1 )
      - nodeName của một văn bản ( text node ) sẽ trả về #text
      - nodeName của một chú thích ( comment node ) sẽ trả về #comment
Ví dụ :
<p id="01">Vnfree.Net</p>
       
        <input type="button" value="Show Nodes Name" id="edit"/>
       
        <script language="javascript">
            // Lấy button
            var button = document.getElementById("edit");

            // Thêm sự kiện click cho button
            button.addEventListener("click", function(){
              
            // Lấy nodeName của thẻ p
            var Node_name = document.getElementById("01").nodeName;
              
            // đưa ra kết quả
            alert(Node_name);
              
          	});
        </script>
Thuộc tính nodeValue :
      Khi ta lấy thuộc tính nodeValue nó sẽ trả về giá trị của một nodes, có đặc điểm sau :
      - nodeValue của một phần tử ( element node ) trả về null
      - nodeValue của một văn bản ( text node ) trả về văn bản
      - nodeValue của một chú thích ( comment node ) trả về chú thích đó

Thuộc tính nodeType :
      Khi ta lấy thuộc tính nodeType nó sẽ trả về một số (Number) , bảng sau thể hiện một số Type thường gặp :
Name Type Mô tả
Element node 1 <h1 class="DomNodes">Vnfree.Net</h1>
Text node 3 Vnfree.Net
Comment node 8 <!-- đây là chú thích -->
Document node 9 là tài liệu HTML, được thể hiện bởi thẻ <html>

Bài này khá dài nhưng nó chỉ khác nhau đôi chút trong các ví dụ, hi vọng giúp ích được cho bạn. Chúc bạn lập trình vui vẻ.