Hướng dẫn lựa chọn phần tử và điều hướng cây DOM bằng JavaScript

Truy xuất phần tử thông qua bộ chọn CSS

Cung cấp khả năng kết hợp cú pháp phức tạp của CSS, hai phương thức tích hợp sẵn trên đối tượng document giúp trích xuất thành phần HTML mục tiêu mà không cần thư viện bên thứ ba.

Lấy phần tử duy nhất nhất khớp đầu tiên

querySelector() quét theo chiều sâu và trả về tham chiếu đến thẻ thỏa mãn điều kiện sớm nhất.

// Gán khối tiêu đề có id="page-title" vào biến mainHeading
const mainHeading = document.querySelector("#page-title");

// Truy cập thẻ Heading mức 1 đầu tiên xuất hiện trong mã nguồn
const topH1 = document.querySelector("h1");

Nhóm toàn bộ phần tử thỏa mãn

Khi cần xử lý tập hợp nhiều đối tượng, querySelectorAll() sẽ tạo ra một NodeList bất biến, cho phép lặp qua từng thành viên.

// Chứa danh sách toàn bộ thẻ liệt kê kiểu dấu chấm
const listItems = document.querySelectorAll("ul li");

Kỹ thuật di chuyển qua cấu trúc phân cấp

JavaScript cung cấp hệ thống thuộc tính riêng biệt để thao tác với Node (nút dữ liệu gốc) và Element (thẻ HTML thực tế). Việc phân biệt rõ ràng giữa hai nhóm này giúp tránh lỗi thường gặp do ký tự xuống dòng hoặc khoảng trắng thừa.

Thuộc tính liên quan đến Node (Nút)

parentNode: Tham chiếu ngược lên nút mẹ trực tiếp. Gốc document sẽ trả về null.

const contentBlock = document.querySelector("#main-wrapper");
contentBlock.parentNode.style.borderTop = "2px dashed #888";

childNodes: Tập hợp tất cả nút con trực tiếp, bao gồm cả văn bản thuần và khoảng trắng định dạng. Kết quả thuộc kiểu NodeList.

const sourceContainer = document.getElementById("source-box");
const rawNodes = sourceContainer.childNodes;

rawNodes.forEach((n, i) => {
  console.log(`Vị trí ${i}: ${n.nodeName}`);
});
console.log(`Tổng nút con: ${rawNodes.length}`);

firstChild & lastChild: Định vị ranh giới trên và dưới của danh sách nút con.

const gridArea = document.querySelector(".panel");
gridArea.firstChild.style.marginTop = "0";
gridArea.lastChild.style.marginBottom = "0";

nextSibling & previousSibling: Di chuyển ngang sang các nút anh em liền kề. Cần lưu ý rằng cấu trúc HTML có thụt lề sẽ tạo ra các Text Node xen kẽ.

const activeTab = document.querySelector("div.tab-active");
const followUp = activeTab.nextSibling;
const priorItem = activeTab.previousSibling;

followUp?.classList.add("highlight");
priorItem?.classList.remove("highlight");

nodeType: Mã hóa định danh cấu trúc dạng số nguyên:

  • 1: Element (Thẻ HTML)
  • 3: Text (Nội dung chuỗi)
  • 8: Comment (Nhận xét ẩn)
  • 9: Document (Căn cứ tài liệu)
  • 11: DocumentFragment

nodeValue & nodeName: nodeValue chỉ khả dụng cho Text/Comment nodes nhằm đọc hoặc gán nội dung chữ. nodeName luôn trả về định danh thẻ ở ký tự hoa, dùng để nhận diện cấu trúc gốc.

const demoNode = document.querySelector("#sandbox");

// Xuất giá trị chuỗi bên trong
console.log(demoNode.firstChild.nodeValue);

// Xuất tên thẻ viết hoa
console.log(demoNode.nodeName);

Thuộc tính chuyên biệt cho Element (Phần tử)

Nhóm này bỏ qua hoàn toàn Text Node và Focus trực tiếp vào các đối tượng HTML thực sự, giảm thiểu rủi ro lập trình.

children: Danh sách thuần các HTMLElement con.

const parentGrid = document.querySelector(".card-container");
const pureElements = parentGrid.children;

Array.from(pureElements).forEach(el => {
  el.style.opacity = "0.9";
});

firstElementChild & lastElementChild: Cắt ngắn khoảng trắng và nhắm thẳng vào phần tử con đầu/cuối.

const menuWrapper = document.querySelector("nav.primary-nav");
menuWrapper.firstElementChild.style.textTransform = "uppercase";
menuWrapper.lastElementChild.style.textTransform = "capitalize";

nextElementSibling & previousElementSibling: Di chuyển ngang qua các thẻ HTML kế cận, loại trừ khoảng trắng định dạng.

const currentSection = document.querySelector("section.featured");
currentSection.nextElementSibling?.setAttribute("data-status", "loaded");
currentSection.previousElementSibling?.removeAttribute("data-loaded");

childElementCount: Trả về số lượng phần tử con trực tiếp dưới dạng số nguyên, tối ưu cho việc tính toán bố cục động.

const sliderBoard = document.querySelector(".track");
console.log(`Số slide hiện hành: ${sliderBoard.childElementCount}`);

Mẹo kiểm thử: Sao chép các đoạn mã ví dụ vào tab Console của trình duyệt (mở bằng phím F12) để chạy mô phỏng trực tiếp và quan sát kết quả trả về ngay lập tức.

Thẻ: DOM-API JavaScript-Selector DocumentTraversal Browser-Native-API Frontend-Navigation

Đăng vào ngày 8 tháng 9 lúc 18:01