Thứ hai, 20/11/2017 | 00:00 GMT+7

Cách truy cập các phần tử trong DOM

Trong phần Tìm hiểu về cây và nút DOM , ta đã xem xét cách DOM được cấu trúc như một cây các đối tượng được gọi là nút và các node có thể là văn bản, comment hoặc phần tử. Thông thường khi ta truy cập nội dung trong DOM, nó sẽ thông qua một nút phần tử HTML.

Để có thể truy cập thành thạo các phần tử trong DOM, cần phải có kiến thức về bộ chọn CSS, cú pháp và thuật ngữ cũng như hiểu biết về các phần tử HTML. Trong hướng dẫn này, ta sẽ xem xét một số cách để truy cập các phần tử trong DOM: theo ID, lớp, thẻ và bộ chọn truy vấn.

Tổng quat

Dưới đây là bảng tổng quan về năm phương pháp mà ta sẽ đề cập trong hướng dẫn này.

Được Cú pháp bộ chọn phương pháp
TÔI #demo getElementById()
Lớp học .demo getElementsByClassName()
Nhãn demo getElementsByTagName()
Bộ chọn (đơn) querySelector()
Bộ chọn (tất cả) querySelectorAll()

Điều quan trọng khi nghiên cứu DOM là nhập các ví dụ trên máy tính của bạn đảm bảo rằng bạn đang hiểu và lưu giữ thông tin bạn học.

Bạn có thể lưu file HTML này, access.html , vào dự án của bạn để làm việc thông qua các ví dụ cùng với bài viết này. Nếu bạn không chắc chắn về cách làm việc với JavaScript và HTML local , hãy xem lại hướng dẫn Cách Thêm JavaScript vào HTML của ta .

access.html
<!DOCTYPE html> <html lang="en">  <head>   <meta charset="utf-8">   <meta name="viewport" content="width=device-width, initial-scale=1.0">    <title>Accessing Elements in the DOM</title>    <style>     html { font-family: sans-serif; color: #333; }     body { max-width: 500px; margin: 0 auto; padding: 0 15px; }     div, article { padding: 10px; margin: 5px; border: 1px solid #dedede; }   </style>  </head>  <body>    <h1>Accessing Elements in the DOM</h1>    <h2>ID (#demo)</h2>   <div id="demo">Access me by ID</div>    <h2>Class (.demo)</h2>   <div class="demo">Access me by class (1)</div>   <div class="demo">Access me by class (2)</div>    <h2>Tag (article)</h2>   <article>Access me by tag (1)</article>   <article>Access me by tag (2)</article>    <h2>Query Selector</h2>   <div id="demo-query">Access me by query</div>    <h2>Query Selector All</h2>   <div class="demo-query-all">Access me by query all (1)</div>   <div class="demo-query-all">Access me by query all (2)</div>  </body>  </html> 

Trong file HTML này, ta có nhiều phần tử mà ta sẽ truy cập bằng các phương thức document khác nhau. Khi ta hiển thị file trong trình duyệt, file sẽ trông giống như sau:

Trình duyệt hiển thị trang access.html

Ta sẽ sử dụng các phương pháp khác nhau mà ta đã nêu trong phần Tổng quan ở trên để truy cập các phần tử có sẵn trong file .

Truy cập các phần tử theo ID

Cách dễ nhất để truy cập một phần tử trong DOM là bằng ID duy nhất của nó. Ta có thể lấy một phần tử theo ID bằng phương thức getElementById() của đối tượng document .

document.getElementById(); 

Để được ID truy cập, phần tử HTML phải có thuộc tính id . Ta có một phần tử div với một ID của demo .

<div id="demo">Access me by ID</div> 

Trong Console , ta hãy lấy phần tử và gán nó vào biến demoId .

  • const demoId = document.getElementById('demo');

Đăng nhập demoId vào console sẽ trả về toàn bộ phần tử HTML của ta .

  • console.log(demoId);
Output
<div id="demo">Access me by ID</div>

Ta có thể chắc chắn rằng ta đang truy cập đúng phần tử bằng cách thay đổi thuộc tính border thành purple .

  • demoId.style.border = '1px solid purple';

Khi ta làm như vậy, trang trực tiếp của ta sẽ trông như thế này:

Trình duyệt hiển thị kiểu phần tử ID

Truy cập một phần tử theo ID là một cách hiệu quả để nhanh chóng nhận được một phần tử trong DOM. Tuy nhiên, nó có nhược điểm; ID phải luôn là duy nhất cho trang và do đó bạn sẽ chỉ có thể truy cập vào một phần tử duy nhất tại một thời điểm bằng phương thức getElementById() . Nếu bạn muốn thêm một hàm vào nhiều phần tử trên toàn bộ trang, mã của bạn sẽ nhanh chóng trở nên tốt hơn.

Truy cập các phần tử theo lớp

Thuộc tính class được sử dụng để truy cập một hoặc nhiều phần tử cụ thể trong DOM. Ta có thể lấy tất cả các phần tử có tên lớp đã cho bằng phương thức getElementsByClassName() .

document.getElementsByClassName(); 

Bây giờ ta muốn truy cập nhiều hơn một phần tử và trong ví dụ của ta , ta có hai phần tử với một lớp demo .

<div class="demo">Access me by class (1)</div> <div class="demo">Access me by class (2)</div> 

Hãy truy cập các phần tử của ta trong Control panel và đặt chúng vào một biến có tên là demoClass .

  • const demoClass = document.getElementsByClassName('demo');

Đến đây, bạn có thể nghĩ rằng bạn có thể sửa đổi các phần tử giống như cách bạn đã làm với ví dụ ID. Tuy nhiên, nếu ta cố gắng chạy đoạn mã sau và thay đổi thuộc tính border của các phần tử demo của lớp thành màu cam, ta sẽ gặp lỗi.

  • demoClass.style.border = '1px solid orange';
Output
Uncaught TypeError: Cannot set property 'border' of undefined

Lý do điều này không hoạt động là vì thay vì chỉ nhận một phần tử, ta có một đối tượng giống như mảng của các phần tử.

  • console.log(demoClass);
Output
(2) [div.demo, div.demo]

Mảng JavaScript phải được truy cập bằng một số index . Do đó, ta có thể thay đổi phần tử đầu tiên của mảng này bằng cách sử dụng chỉ số 0 .

  • demoClass[0].style.border = '1px solid orange';

Nói chung khi truy cập các phần tử theo lớp, ta muốn áp dụng một thay đổi cho tất cả các phần tử trong tài liệu với lớp cụ thể đó, không chỉ một. Ta có thể làm điều này bằng cách tạo một vòng lặp for và lặp qua mọi mục trong mảng.

  • for (i = 0; i < demoClass.length; i++) {
  • demoClass[i].style.border = '1px solid orange';
  • }

Khi ta chạy mã này, trang trực tiếp của ta sẽ được hiển thị như sau:

Trình duyệt hiển thị kiểu phần tử lớp

Bây giờ ta đã chọn mọi phần tử trên trang có lớp demo và thay đổi thuộc tính border thành orange .

Truy cập các phần tử bằng thẻ

Một cách ít cụ thể hơn để truy cập nhiều phần tử trên trang là tên thẻ HTML của nó. Ta truy cập một phần tử bằng thẻ với phương thức getElementsByTagName() .

document.getElementsByTagName(); 

Đối với ví dụ về thẻ của ta , ta đang sử dụng các phần tử article .

<article>Access me by tag (1)</article> <article>Access me by tag (2)</article> 

Giống như truy cập một phần tử theo lớp của nó, getElementsByTagName() sẽ trả về một đối tượng giống như mảng của các phần tử và ta có thể sửa đổi mọi thẻ trong tài liệu bằng vòng lặp for .

  • const demoTag = document.getElementsByTagName('article');
  • for (i = 0; i < demoTag.length; i++) {
  • demoTag[i].style.border = '1px solid blue';
  • }

Khi chạy mã, trang trực tiếp sẽ được sửa đổi như sau:

Trình duyệt hiển thị kiểu phần tử thẻ

Vòng lặp đã thay đổi thuộc tính border của tất cả các phần tử article thành blue .

Bộ chọn truy vấn

Nếu bạn có kinh nghiệm nào với API jQuery , bạn có thể quen thuộc với phương pháp truy cập DOM của jQuery bằng các bộ chọn CSS.

$('#demo'); // returns the demo ID element in jQuery 

Ta có thể làm điều tương tự trong JavaScript thuần túy với các phương thức querySelector()querySelectorAll() .

document.querySelector(); document.querySelectorAll(); 

Để truy cập một phần tử duy nhất, ta sẽ sử dụng phương thức querySelector() . Trong file HTML của ta , ta có một phần tử demo-query

<div id="demo-query">Access me by query</div> 

Bộ chọn cho thuộc tính id là ký hiệu băm ( # ). Ta có thể gán phần tử có id demo-query cho biến demoQuery .

  • const demoQuery = document.querySelector('#demo-query');

Trong trường hợp bộ chọn có nhiều phần tử, chẳng hạn như một lớp hoặc một thẻ, querySelector() sẽ trả về phần tử đầu tiên phù hợp với truy vấn. Ta có thể sử dụng phương thức querySelectorAll() để thu thập tất cả các phần tử phù hợp với một truy vấn cụ thể.

Trong file ví dụ của ta , ta có hai phần tử với lớp demo-query-all được áp dụng cho chúng.

<div class="demo-query-all">Access me by query all (1)</div> <div class="demo-query-all">Access me by query all (2)</div> 

Bộ chọn cho một thuộc tính class là dấu chấm hoặc dấu chấm ( . ), Vì vậy ta có thể truy cập lớp bằng .demo-query-all .

  • const demoQueryAll = document.querySelectorAll('.demo-query-all');

Sử dụng phương thức forEach() , ta có thể áp dụng màu green cho thuộc tính border của tất cả các phần tử phù hợp.

  • demoQueryAll.forEach(query => {
  • query.style.border = '1px solid green';
  • });

Trình duyệt hiển thị kiểu querySelector ()

Với querySelector() , các giá trị được phân tách bằng dấu phẩy hoạt động như một toán tử OR. Ví dụ: querySelector('div, article') sẽ trùng với div hoặc article , tùy theo cái nào xuất hiện đầu tiên trong tài liệu. Với querySelectorAll() , các giá trị được phân tách bằng dấu phẩy hoạt động như một toán tử AND và querySelectorAll('div, article') sẽ trùng với tất cả các giá trị div article trong tài liệu.

Việc sử dụng các phương thức của bộ chọn truy vấn là cực kỳ mạnh mẽ, vì bạn có thể truy cập bất kỳ phần tử hoặc group phần tử nào trong DOM giống như cách bạn làm trong file CSS. Để có danh sách đầy đủ các bộ chọn, hãy xem lại Bộ chọn CSS trên Mạng nhà phát triển Mozilla.

Hoàn thành mã JavaScript

Dưới đây là kịch bản hoàn chỉnh của công việc ta đã làm ở trên. Bạn có thể sử dụng nó để truy cập tất cả các phần tử trên trang mẫu của ta . Lưu file như access.js và tải nó vào file HTML ngay trước khi bế mạc body thẻ.

access.js
// Assign all elements const demoId = document.getElementById('demo'); const demoClass = document.getElementsByClassName('demo'); const demoTag = document.getElementsByTagName('article'); const demoQuery = document.querySelector('#demo-query'); const demoQueryAll = document.querySelectorAll('.demo-query-all');  // Change border of ID demo to purple demoId.style.border = '1px solid purple';  // Change border of class demo to orange for (i = 0; i < demoClass.length; i++) {   demoClass[i].style.border = '1px solid orange'; }  // Change border of tag demo to blue for (i = 0; i < demoTag.length; i++) {   demoTag[i].style.border = '1px solid blue'; }  // Change border of ID demo-query to red demoQuery.style.border = '1px solid red';  // Change border of class query-all to green demoQueryAll.forEach(query => {   query.style.border = '1px solid green'; }); 

Tệp HTML cuối cùng của bạn sẽ trông giống như sau:

access.html
<!DOCTYPE html> <html lang="en">  <head>   <meta charset="utf-8">   <meta name="viewport" content="width=device-width, initial-scale=1.0">    <title>Accessing Elements in the DOM</title>    <style>     html { font-family: sans-serif; color: #333; }     body { max-width: 500px; margin: 0 auto; padding: 0 15px; }     div, article { padding: 10px; margin: 5px; border: 1px solid #dedede; }   </style>  </head>  <body>    <h1>Accessing Elements in the DOM</h1>    <h2>ID (#demo)</h2>   <div id="demo">Access me by ID</div>    <h2>Class (.demo)</h2>   <div class="demo">Access me by class (1)</div>   <div class="demo">Access me by class (2)</div>    <h2>Tag (article)</h2>   <article>Access me by tag (1)</article>   <article>Access me by tag (2)</article>    <h2>Query Selector</h2>   <div id="demo-query">Access me by query</div>    <h2>Query Selector All</h2>   <div class="demo-query-all">Access me by query all (1)</div>   <div class="demo-query-all">Access me by query all (2)</div>    <script src="access.js"></script>  </body>  </html> 

Bạn có thể tiếp tục làm việc trên các file mẫu này để áp dụng các thay đổi bổ sung bằng cách truy cập các phần tử HTML.

Kết luận

Trong hướng dẫn này, ta đã xem xét 5 cách để truy cập các phần tử HTML trong DOM - theo ID, theo lớp, theo tên thẻ HTML và theo bộ chọn. Phương pháp bạn sẽ sử dụng để lấy một phần tử hoặc group các phần tử sẽ phụ thuộc vào sự hỗ trợ của trình duyệt và số lượng phần tử bạn sẽ thao tác. Đến đây bạn sẽ cảm thấy tự tin khi truy cập bất kỳ phần tử HTML nào trong tài liệu bằng JavaScript thông qua DOM.


Tags:

Các tin liên quan