Cảm ơn bạn!
Phân biệt firstChild vs firstElementChild trong JavaScript
Khi thao tác DOM với JavaScript, các bạn có thể đã gặp những firstChild
, firstElementChild
, lastChild
và lastElementChild
. Đây là những thuộc tính nếu không phân biệt được chúng, sẽ dẫn đến việc sử dụng không cho kết quả như mong muốn. Cùng xem chúng khác nhau ở đâu trong bài viết này nhé!
firstChild vs firstElementChild JavaScript
firstChild
và firstElementChild
là hai thuộc tính read-only, kết quả trả về ở một số trường hợp sẽ không giống nhau, xem ví dụ dưới đây để hiểu hơn nhé ^^.
<body>
<div class="homiedev-data"></div>
<script>
const homiedevEle = document.querySelector(".homiedev-data");
console.log(homiedevEle.firstChild); // null
console.log(homiedevEle.firstElementChild); // null
</script>
</body>
Kết quả cả hai thuộc tính đều trả về null là vì phần tử homiedevEle
không chứa bất kì node con nào ^^.
Tuy nhiên nếu ta thêm một khoảng trắng vào homiedevEle
thì kết quả sẽ như sau.
<body>
<div class="homiedev-data"> </div>
<script>
const homiedevEle = document.querySelector(".homiedev-data");
console.log(homiedevEle.firstChild); // " " => một khoảng trắng
console.log(homiedevEle.firstElementChild); // null
</script>
</body>
Ta thấy thuộc tính firstChild
cho kết quả là " "
, vì thuộc tính này trả về bất kỳ loại node nào là node con đầu tiên của homiedevEle
. Node
là tên chung cho bất kỳ loại object trong DOM, node có nhiều kiểu, một node có thể là element node, text node, comment node,...
Ở ví dụ trên, ta có thể thấy firstChild
trả về một text node. Với firstElementChild
, nó trả về element node con đầu tiên của homiedevEle
, các bạn có thể thấy không có element nào nên kết quả là null.
Thông thường nếu sử dụng console.log(homiedevEle.firstChild);
nó sẽ trả về giá trị " "
. Ta có thể chuyển sang dạng JavaScript object bằng cách sử dụng format specifiers.
// console.log(homiedevEle.firstChild); kết quả: " "
// console.log('%O', homiedevEle.firstChild);
Sử dụng %O
ta sẽ nhận được kết quả là text node dưới dạng object.
{
data: " ",
firstChild: null,
isConnected: true,
lastChild: null,
length: 1,
nextElementSibling: null,
nextSibling: null,
nodeName: "#text",
nodeType: 3,
nodeValue: " ",
// còn nhiều thuộc tính khác
};
Nếu ta thêm một element node cho homiedevEle
thì kết quả của firstChild
và firstElementChild
sẽ là gì? các bạn nghĩ thử và xem kết quả nhé.
<body>
<div class="homiedev-data">
<span>URL: </span>
<a href="https://homiedev.com">Homiedev</a>
</div>
<script>
const homiedevEle = document.querySelector(".homiedev-data");
// homiedevEle.firstChild) => #text object
// homiedevEle.firstElementChild => <span>URL: </span>
</script>
</body>
Khi sử dụng firstChild
trong ví dụ trên, ở console
ta nhận được #text
object, lý do là vì ta đã cho <span>URL: </span>
xuống dòng mới và thêm một vài khoảng trống so với đầu dòng, lúc này một text node đã được thêm vào, nhìn nó thế này "\n ". Và như vậy đây sẽ là first child của homiedevEle
khi sử dụng thuộc tính firstChild
. Với firstElementChild
ta nhận được element <span>URL: </span>
, vì đây là một element node và nó là element con đầu tiên của homiedevEle
.
Giả sử ta không thêm khoảng trắng (whitespace) giữa thẻ <div class="homiedev-data">
và <span>URL: </span>
thì giá trị của firstChild
và firstElementChild
là giống nhau.
<body>
<div class="homiedev-data"><span>URL: </span>
<a href="https://homiedev.com">Homiedev</a>
</div>
<script>
console.log(homiedevEle.firstChild === homiedevEle.firstElementChild); // true
</script>
</body>
Vì firstChild
trả về bất kỳ loại node nào là node con của homiedevEle
, cho nên trong trường hợp này, nó cho cùng kết quả với firstElementChild
là node element <span>URL: </span>
.
👉 Nếu so sánh lastChild
vs lastElementChild
thì cũng tương tự như firstChild
vs firstElementChild
, chúng chỉ khác ở điểm lastChild
sẽ trả về bất kỳ loại node nào là con cuối của parent element, lastElementChild
thì trả về element node cuối của parent element ^^.
Như vậy là chúng ta đã tìm hiểu xong sự khác nhau giữa firstChild
vs firstElementChild
, tương tự với lastChild
vs lastElementChild
. Nếu có bất kỳ thắc mắc nào với nội dung liên quan, các bạn có thể để lại bình luận bên dưới nhé 😃.
Cảm ơn các bạn đã đọc bài viết, chúc các bạn học tốt 🎉.