Mô hình DOM trong javascript

Mô hình DOM trong javascript – là mô hình phân cấp các tag trong tài liệu HTML. Nó mô tả cấu trúc phân tầng các tag được bố trí trong trang web.


Giới thiệu về mô hình DOM

Khi trình duyệt đọc cấu trúc html của trang web, nó sẽ xây dựng nên một mô hình có thứ bậc phân cấp để diễn tả cấu trúc html trong trang, gọi là mô hình DOM.

Mô hình DOM là 1 trong các chuẩn của tổ chức W3C – tổ chức quy định các chuẩn cho web. DOM quy định cách thức mà trình duyệt xây dựng cây phân cấp. Nhờ DOM, bạn dùng Javascript mới có thể:

  • Chỉnh nội dung các tag HTML
  • Chỉnh thuộc tính  các tag HTML
  • Chỉnh định dạng CSS các tag HTML
  • Xóa các tag và thuộc tính không mong muốn
  • Thêm các tag HTML mới.
  • Tương tác với các sự kiện của các tag

Node trong mô hình DOM

Mỗi thành phần trong DOM gọi là 1 Node. Mỗi node có những thuộc tính và hàm riêng.

<html>
    <head>
        <title>My Title</title>
    </head>
    <body>
        <a href="index.html">My link</a>
        <h1>My header</h1>
    </body>
</html>
mô hình dom
  • Node đầu tiên trong DOM được gọi là root (gốc), đó là node document
  • Giữa các node trong DOM có mối quan hệ cha, con và anh em (siblings).
  • Tất cả các node, ngoại trừ root chỉ có một cha
  • Một node có thể có nhiều con hoặc không có con nào
  • Node lá (leaf) không có con
  • Những node anh em (siblings) với nhau có cùng một cha.

Tóm lại, mô hình DOM trong javascript giống như một cái cây có gốc và nhiều cành nhánh. Gốc cây là node gốc và các cành nhánh là các node con cháu.

Các loại node trong DOM

Có nhiều loại node trong DOM, mời xem bảng sau:

  • document node: là node diễn tả toàn bộ tài liệu
  • element node: là loại node diễn các tag html đang dùng trong trang web. Ví dụ br, img
  • comment node: là node chứa các ghi chú trong tài liệu
  • attribute node:  là node chứa thuộc tính của các tag
  • text node: là node chứa chữ trong các tag

Các thuộc tính và hàm trong một node

Trong mô hình DOM, mỗi node có nhiều thuộc tính và nhiều hàm

Các thuộc tính trong một node

Thuộc tính Mô tả
attributesMảng là các thuộc tính của node
childElementCountĐếm các element con
childNodesMảng các con của node, gồm cả text và comment node
childrenMảng các element con, không gồm text và comment node
classListTrả về các class css
classNameThuộc tính class css
clientHeightĐộ cao của node, gồm cả padding
clientLeftTrả về độ lớn border trái của element
clientTopTrả về độ lớn border trên của element
clientWidthĐộ rộng của node, gồm cả padding
contentEditableTrạng thái cho phép soạn thảo nội dung
firstChildNode con đầu tiên
idId của node
innerHTMLCode html
innerTextGán hoặc trả về text trong element (không có code html)
lastChildLấy node con cuối .
nextElementSiblingLấy element kế tiếp .
nodeNameTrả về tên node
nodeTypeCho biết kiểu của node (element, text, attribute…)
parentElementTrả về node cha
previousElementSiblingLấy element node trước của node hiện tại
styleTập hơp các thuộc tính css của node
tagNameTên tag

Các hàm trong một node

appendChild()Thêm node con
click()Hàm chạy khi click chuột vào element
blur()Hàm chạy khi element mất focus
contains()Hàm trả về tru true nếu nó chứa 1 node chỉ ra, ngược lại trả về false
focus()Hàm chạy khi element có focus
getAttribute()Hàm trả về giá trị của 1 thuộc tính html
getBoundingClientRect()Returns the size of an element and its position relative to the viewport
getElementsByClassName()Lấy mảng các element theo class css
getElementsByTagName()Lấy mảng các element theo tag
hasAttribute()Trả về true true nếu element có thuộc tính đã chỉ ra , ngược lại trả về false
insertBefore()Chèn node con ở trước node chỉ định
setAttribute()Hàm giúp gán giá trị cho 1 thuộc tính html của node
querySelector()Hàm giúp chọn node trong DOM theo điều kiện chỉ ra
remove()Hàn dùng để xóa node hiện tại ra khỏi DOM
removeAttribute()Xóa thuộc tính do bạn chỉ ra attribute
removeChild()Xóa node con khỏi element

Chọn node trong DOM bằng Javascript

Có thể chọn các node trong DOM bằng các hàm Javascript sau:

  • getElementById(id) : Trả về node có thuộc tính id chỉ định
  • getElementsByName(name): Trả về 1 mảng các node có name chỉ định
  • getElementsByTagName(name):Trả về  1 mảng các node có tên tag chỉ định
  • getElementsByClassName(name):Trả về  1mảng các node có class chỉ định

Ngoài ra có thể sử dụng mối quan hệ cha , con, láng giềng, trước sau giữa các node để truy cập các node.

<body>
<ul id="dsHoa" class="abc"><li>Hoa Hồng</li><li>Hoa Lan</li></ul><hr>
<script>
var h = document.getElementById("dsHoa");  //biến h là 1 node trong DOM
document.write("<p>Tên node: " + h.nodeName + "</p>");
document.write("<p>Node cha: " + h.parentElement.nodeName + "</p>");
document.write("<p>Node con đầu tiên: " + h.firstChild.innerText + "</p>");
document.write("<p>Node con thu hai: " + h.childNodes[1].innerText+ "</p>");
document.write("<p>Node Type: " + h.nodeType+ "</p>");
document.write("<xmp>Mã html: " + h.innerHTML+ "</xmp>");
document.write("<p>Text : " + h.innerText+ "</p>");
console.log(h);
console.log(h.attributes);
console.log(h.childNodes);
h.childNodes[1].innerText = "Hoa Phượng";
h.firstChild.innerText = "Hoa Mai";
</script>
</body>
<body>
    <h2 id="tp">THƠ HAY</h2>
    <h3 class="vt">CHA ĐÓ</h3>
    <p>Đường xa heo hút dặm ngàn<br>Đời cha vất vả gian nan thác ghềnh.</p>
    <p>Sông dài biển rộng trời cao.<br>Công Cha tôi cũng không sao sánh bằng. </p> 
    <h3 class="vt">MẸ ĐÂY</h3>
    <p name="c2"> Mẹ tôi hai tiếng thân thươnng<br/>Ôi hai tiếng ấy quý dường ngọc châu</p>
    <p> Mẹ ơi con chịu bao điều<br/> Nhưng không chịu nổi thân diều đứt dây</p>
    <hr>
    <h2>Bạn nhớ tới Mẹ khi nào:</h2>
    <input type="checkbox" name="me" value="1">Đói<br>
    <input type="checkbox" name="me" value="2">No<br>
    <input type="checkbox" name="me" value="3">Bệnh
    <hr>
</body>
<script>
    var x = document.getElementById('tp'); console.log(x.innerHTML);
    arr = document.getElementsByName("me"); console.log(arr);
    arr = document.getElementsByTagName("h2"); console.log(arr);
    arr = document.getElementsByClassName("vt"); console.log(arr);
</script>

Thêm node vào DOM

Sử dụng hàm appendChild để thêm node.

Thêm text vào tag có sẵn

<button onclick="themtext()">Thêm text</button> <p id="doan1"></p>
<script>
function themtext() {
    var tn = document.createTextNode("Hãy tập sống thương yêu");
    var p = document.getElementById("doan1");
    p.appendChild(tn);
}
</script>

Thêm paragraph chứa text

Tạo textnode rồi tạo tag p, thêm textnode vào tag p rồi thêm tag p vào node cha.

<button onclick="themtagp()">Thêm đoạn</button> <div id="txn"></div>
<script>
function themtagp() {
    var chu = document.createTextNode("Có rất nhiều niềm vui thanh tao");
    var tagp = document.createElement("p");
    tagp.appendChild(chu);
    document.getElementById("txn").appendChild(tagp);
}
</script>

Xóa node khỏi DOM

Muốn xóa node khỏi DOM, bạn dùng hàm removeChild

<ul id="thucung"> <li>Chó</li> <li>Mèo</li><li>Chim</li></ul>
<button onclick="abc()">Xóa mục đầu</button>
<script>
function abc() {
  var list = document.getElementById("thucung");
  list.removeChild(list.childNodes[0]);
}
</script>
<!-- Chú ý  <li> không có khoảng trắng ở đầu -->

Tham khảo thêm

https://www.w3schools.com/js/js_htmldom.asp
https://www.w3schools.com/whatis/whatis_htmldom.asp

Mời xem ví dụ tổng hợp sau để xem cách chỉnh định dạng đối tượng

<style>
    #tbl { width: 4ppx; margin: auto; border-collapse: collapse;}
    #tbl td { border: 1px solid darkblue; padding: 4px;}
    h2, h3 { text-align: center;}
</style>
<h2>Thực tập : Chỉnh định dạng đối tượng</h2>
<table id="tbl"> 
    <tr id="dong1">
        <td>Dòng 1 - ô 1 </td>
        <td><span>Dòng 1 - <b>ô 2</b> </span></td>
        <td>Dòng 1 - ô 3 </td>
    </tr>
    <tr id="dong2">
        <td>Dòng 2 - ô 1 </td>
        <td>Dòng 2 - ô 2 </td>
        <td>Dòng 2 - ô 3 </td>
    </tr>
</table>
<h3>
    <button onclick="an()">Ẩn</button>
    <button onclick="hien()">Hien</button>
    <button onclick="chinhmaunen()">Chỉnh màu nền</button>
    <button onclick="chuhoa()">Cột cuối chữ hoa</button>
</h3>
<script>
function chuhoa(){
    tr_arr = document.getElementsByTagName("tr");
    for(var i=0; i<tr_arr.length ; i++){
        var str = tr_arr[i].children[2].innerText.toUpperCase();
        tr_arr[i].children[2].innerHTML = "<b>" + str +"</b>";
    }
}
function chinhmaunen(){
    mau = prompt("Nhập màu");
    obj = document.getElementById("tbl");
    obj.style.backgroundColor=mau;
}
function hien(){
    obj = document.getElementById("tbl");
    obj.style.display="";
}
function an(){
    obj = document.getElementById("tbl");
    obj.style.display="none";
}
function testchildren(){
    var obj =  document.getElementById("dong1");
    var socon = obj.children.length;
    console.log("Số con " + socon) ;
    var str = obj.children[1].innerHTML;
    console.log("Mã trong ô thứ 2 : " + str);
    var text = obj.children[1].innerText;
    console.log("Mã trong ô thứ 2 : " + text);
}
</script>
<script> testchildren();</script>

Xem ví dụ sau để biết cách chọn đối tượng theo class, theo tag, khóa nút, sửa nội dung

<style>
.cacsothich {
    width: 300px; margin: auto; border: solid 2px darkkhaki ; 
    padding: 0 20px; font-size: 1.1em; }
</style>
<div id="sothich">
    <h3>Sở thích của bạn là gì?</h3>
    <p> <span class="st"> Nhìn mua rơi</span> <em>13 </em> </p>
    <p> <span class="st"> Nghe chim hót</span> <em>15 </em> </p>
    <p> <span class="st"> Ngắm mây bay</span> <em>17 </em> </p>
    <p> <span class="st"> Uống trà</span> <em>20 </em> </p>
    <p> <span class="st"> Vuốt râu</span> <em> 25 </em> </p>
</div><hr>
<button onclick="xuly()">Xử lý</button>
<script>
function xuly(){
    var arr = document.getElementsByClassName("st");
    for(var i=0; i<arr.length ; i++){
        var sp = arr[i];       
        var em = sp.parentNode.getElementsByTagName("em")[0];
        var solan = em.innerText;
        em.innerText="";
        sp.innerText = sp.innerText.toUpperCase();
        sp.innerText = solan + ". " + sp.innerText;
    }
    document.getElementById("sothich").className="cacsothich";
    document.getElementsByTagName("button")[0].disabled=true;
}
</script>

Thực tập lấy giá trị của đối tượng hiện tại, chọn đối tượng trước, sau…

<head>
<style>
  #container { width: 500px; margin: auto;   }
  #container p { display: grid; padding: 10px 0;
        grid-template-columns: 200px 100px 70px auto;
        border-bottom: 1px solid lightcoral;        
    }
  #container p b:last-child { text-align: right;}
</style>
</head>
<body>
<div id="container">
<p> <span>Nói với tuổi 20</span>
    <b class="gia">56000</b><input value="10" onkeyup="tien(this)"><b class="tien">560000</b>
</p>
<p> <span>Mùi Hương Trầm</span>
    <b class="gia">120000</b><input value="10" onkeyup="tien(this)"><b class="tien">560000</b>
</p>
<p> <span>Hiểu về trái tim</span>
    <b class="gia">100000</b><input value="5" onkeyup="tien(this)"><b class="tien">500000</b>
</p>
</div>
</body>

<script>
function tien(obj){
    var soluong = obj.value;   
    var gia= ...; //lấy nội dung của đối tượng trước
    var tien=...; 
    //gán tiền vào dối  tượng sau

}
</script>

Mời bạn đọc các bài liên quan để bổ sung kiến thức: