Sử dụng Selectors để truy xuất phần tử DOM với JavaScript / jQuery

Javascript căn bản | by Học Javascript

Khi làm việc với giao diện web, việc truy xuất và thao tác với các phần tử HTML (DOM - Document Object Model) là một trong những nhiệm vụ quan trọng nhất của lập trình viên frontend. Để thực hiện điều đó, selectors đóng vai trò như “chiếc cầu nối” giúp chúng ta xác định chính xác phần tử cần làm việc. Dù bạn sử dụng JavaScript thuần hay thư viện jQuery, selectors đều giúp tiết kiệm thời gian và đơn giản hóa việc tương tác với giao diện. Bài viết này sẽ hướng dẫn cách sử dụng selectors hiệu quả trong cả JavaScript và jQuery, giúp bạn làm chủ việc thao tác DOM một cách linh hoạt và tối ưu.

Selectors là gì?

Selectors là các cú pháp dùng để chọn các phần tử trong DOM (Document Object Model). Khi lập trình viên muốn thao tác hoặc truy xuất các phần tử trong trang HTML, họ sẽ sử dụng selectors để định vị các phần tử này. Các selectors giống như các CSS selectors, nhưng thay vì chỉ dùng để áp dụng kiểu dáng (style), chúng ta sử dụng chúng trong JavaScript và jQuery để xử lý các logic, sự kiện, và dữ liệu liên quan đến phần tử DOM.

Với selectors, chúng ta có thể dễ dàng truy xuất và thao tác với phần tử trong DOM, như thay đổi nội dung, áp dụng sự kiện, hoặc thay đổi thuộc tính của phần tử đó.

Selectors trong JavaScript (DOM API)

JavaScript cung cấp một số phương thức để truy xuất các phần tử DOM, giúp lập trình viên có thể dễ dàng làm việc với các phần tử trong trang web. Dưới đây là các selectors phổ biến trong JavaScript:

getElementById()

Phương thức getElementById() được sử dụng để chọn phần tử DOM duy nhất dựa trên giá trị id của phần tử. Mỗi phần tử trong trang chỉ có thể có một id duy nhất, vì vậy phương thức này chỉ trả về một phần tử.

Cú pháp: document.getElementById(id)

Ví dụ:

let myDiv = document.getElementById('myDiv');

Giải thích: Phương thức này trả về phần tử có id="myDiv". Nếu không tìm thấy, kết quả trả về là null.

getElementsByClassName()

Phương thức getElementsByClassName() trả về một HTMLCollection (danh sách các phần tử) chứa tất cả các phần tử DOM có class name khớp với tên lớp đã chỉ định.

Cú pháp: document.getElementsByClassName(className)

Ví dụ:

let items = document.getElementsByClassName('item');

Giải thích: Phương thức này tìm tất cả các phần tử có class item và trả về một HTMLCollection. HTMLCollection giống như một mảng, nhưng không phải là một mảng thực sự, vì vậy cần lưu ý khi làm việc với nó.

getElementsByTagName()

Phương thức getElementsByTagName() được sử dụng để chọn tất cả các phần tử DOM dựa trên tên thẻ (tag name). Kết quả trả về là một HTMLCollection chứa các phần tử đó.

Cú pháp: document.getElementsByTagName(tagName)

Ví dụ:

let paragraphs = document.getElementsByTagName('p');

Giải thích: Phương thức này trả về tất cả các phần tử <p> trong trang. Tương tự như getElementsByClassName(), kết quả là một HTMLCollection.

querySelector()querySelectorAll()

Phương thức querySelector()querySelectorAll() là hai phương thức rất mạnh mẽ, hỗ trợ CSS selector, cho phép truy xuất phần tử hoặc tập hợp phần tử trong DOM. Phương thức này rất linh hoạt và mạnh mẽ vì nó hỗ trợ mọi loại selector giống như trong CSS, bao gồm các selector đơn giản đến phức tạp.

Cú pháp:

  • document.querySelector(selector)

  • document.querySelectorAll(selector)

querySelector(): Trả về phần tử đầu tiên khớp với selector được chỉ định.

querySelectorAll(): Trả về tất cả các phần tử khớp với selector, dưới dạng một NodeList.

Ví dụ:

// Lấy phần tử đầu tiên có class 'box'
let box = document.querySelector('.box');

// Lấy tất cả các phần tử li trong ul
let listItems = document.querySelectorAll('ul li');

Giải thích:

  • querySelector('.box') sẽ trả về phần tử đầu tiên có class box.

  • querySelectorAll('ul li') sẽ trả về một NodeList chứa tất cả các phần tử <li> nằm trong <ul>. Lưu ý rằng NodeList giống như mảng, nhưng không hoàn toàn giống, vì vậy khi duyệt qua nó cần sử dụng vòng lặp hoặc chuyển nó thành mảng nếu cần thiết.

Với các selectors trong JavaScript, bạn có thể dễ dàng chọn và thao tác với các phần tử trong DOM. Các phương thức như getElementById(), getElementsByClassName(), getElementsByTagName(), và querySelector()/querySelectorAll() cho phép bạn linh hoạt chọn các phần tử để xử lý, tạo sự kiện, và làm việc với dữ liệu động.

Selectors trong jQuery

jQuery là một thư viện JavaScript phổ biến giúp việc thao tác với DOM trở nên dễ dàng hơn, đặc biệt trong việc chọn các phần tử và thực hiện các thao tác trên chúng. Một trong những đặc điểm mạnh mẽ của jQuery chính là khả năng sử dụng selectors đơn giản và linh hoạt. Dưới đây là các selectors cơ bản và nâng cao trong jQuery.

Cú pháp cơ bản

Trong jQuery, selectors được sử dụng thông qua hàm $(). Cú pháp của hàm này tương tự như CSS, giúp bạn chọn các phần tử DOM nhanh chóng và dễ dàng.

Ví dụ:

  • $('#id'): Chọn phần tử có id="id".

  • $('.class'): Chọn tất cả các phần tử có class class.

  • $('tag'): Chọn tất cả các phần tử với tên thẻ tag.

  • $('div > p'): Chọn tất cả các phần tử <p> nằm trực tiếp trong phần tử <div>.

Giải thích:

  • $('#id'): Sử dụng selector #id để chọn phần tử có id="id".

  • $('.class'): Chọn tất cả các phần tử có class class. Dấu chấm . đại diện cho class.

  • $('tag'): Chọn tất cả các phần tử có tên thẻ là tag, ví dụ: div, p, h1, v.v.

  • $('div > p'): Chọn tất cả các phần tử <p> là con trực tiếp của các phần tử <div>.

Selector nâng cao

jQuery cung cấp các selectors nâng cao giúp bạn chọn phần tử DOM theo nhiều điều kiện và trạng thái phức tạp hơn:

[attribute=value]: Chọn phần tử có thuộc tính attribute có giá trị value.

  • Ví dụ: $('input[type="text"]'): Chọn tất cả các phần tử <input> có thuộc tính type="text".

:first, :last, :eq(index): Chọn phần tử theo vị trí trong tập hợp phần tử.

  • Ví dụ:

    • $('li:first'): Chọn phần tử <li> đầu tiên trong danh sách.

    • $('li:last'): Chọn phần tử <li> cuối cùng.

    • $('li:eq(2)'): Chọn phần tử <li> ở vị trí chỉ số 2 (lưu ý chỉ số bắt đầu từ 0).

:checked, :disabled, :visible, :hidden: Chọn phần tử dựa trên trạng thái của nó.

  • Ví dụ:

    • $('input:checked'): Chọn tất cả các checkbox hoặc radio button đã được chọn.

    • $('input:disabled'): Chọn tất cả các phần tử <input> bị vô hiệu hóa.

    • $('div:visible'): Chọn tất cả các phần tử <div> đang hiển thị.

    • $('div:hidden'): Chọn tất cả các phần tử <div> đang bị ẩn.

Chọn phần tử trong cây DOM

jQuery còn hỗ trợ các phương thức để truy vấnchọn các phần tử trong cây DOM dựa trên mối quan hệ với các phần tử khác. Các phương thức này giúp bạn dễ dàng đi qua các phần tử con, cha, anh chị em, v.v.

.parent(): Chọn phần tử cha trực tiếp của phần tử hiện tại.

  • Ví dụ: $('.child').parent(): Chọn phần tử cha của phần tử có class child.

.children(): Chọn tất cả các phần tử con trực tiếp của phần tử hiện tại.

  • Ví dụ: $('#parent').children(): Chọn tất cả các phần tử con của phần tử có id="parent".

.find(): Tìm kiếm các phần tử con trong một phần tử theo selector đã cho.

  • Ví dụ: $('#parent').find('p'): Tìm tất cả các phần tử <p> bên trong phần tử có id="parent".

.siblings(): Chọn tất cả các phần tử anh chị em (siblings) của phần tử hiện tại.

  • Ví dụ: $('.child').siblings(): Chọn tất cả các phần tử anh chị em của phần tử có class child.

.closest(): Chọn phần tử cha gần nhất (tương tự như parent(), nhưng có thể chọn bất kỳ phần tử cha nào thỏa mãn selector).

  • Ví dụ: $('.child').closest('.parent'): Chọn phần tử cha gần nhất có class parent của phần tử có class child.

Như vậy, jQuery không chỉ hỗ trợ selectors cơ bản giống CSS, mà còn cung cấp những selectors nâng cao và các phương thức giúp truy xuất phần tử DOM theo mối quan hệ cây DOM, giúp bạn dễ dàng thao tác và xử lý dữ liệu trong các trang web động.

So sánh JavaScript thuần và jQuery trong JavaScript

Cả JavaScript thuần và jQuery đều có khả năng truy xuất và thao tác với các phần tử DOM, tuy nhiên, giữa chúng có những sự khác biệt rõ rệt về cú pháp, khả năng hỗ trợ, hiệu suất và tính dễ sử dụng. Dưới đây là một bảng so sánh chi tiết giữa JavaScript DOM API và jQuery.

JavaScript DOM API:

  • Trong JavaScript thuần, việc thao tác với DOM yêu cầu cú pháp khá dài dòng và cần xử lý thủ công nhiều bước.

  • Ví dụ: Để chọn một phần tử với id="myDiv", bạn cần viết:

var element = document.getElementById("myDiv");

jQuery:

  • jQuery cung cấp cú pháp ngắn gọn và dễ đọc hơn. Chỉ cần sử dụng hàm $() là có thể dễ dàng chọn phần tử và thực hiện các thao tác trên chúng.

  • Ví dụ:

var element = $('#myDiv');
  • So sánh:

    • JavaScript thuần yêu cầu phải viết chi tiết và xử lý nhiều bước hơn, ví dụ như phải xử lý vòng lặp hoặc gọi các hàm tương ứng để truy xuất nhiều phần tử.

    • jQuery giúp rút ngắn đáng kể cú pháp và cho phép thực hiện các thao tác DOM phức tạp chỉ với vài dòng mã.

Hỗ trợ selector CSS

JavaScript DOM API:

  • JavaScript thuần sử dụng querySelectorquerySelectorAll để chọn phần tử theo CSS selector.

  • Ví dụ:

var element = document.querySelector('.className');  // Chọn phần tử đầu tiên
var elements = document.querySelectorAll('.className');  // Chọn tất cả phần tử

jQuery:

  • jQuery hỗ trợ toàn bộ CSS selector, bao gồm các selector cơ bản và nâng cao như :first, :last, :eq(), :checked, :visible, v.v.

  • Ví dụ:

var element = $('.className');  // Chọn tất cả phần tử có class 'className'
var firstElement = $('ul li:first');  // Chọn phần tử <li> đầu tiên trong <ul>

So sánh:

  • Cả JavaScript thuần và jQuery đều hỗ trợ CSS selectors, nhưng jQuery hỗ trợ nhiều selector hơn và dễ dàng sử dụng các pseudo-selectors để chọn các phần tử theo trạng thái hoặc vị trí.

Hỗ trợ trạng thái

JavaScript DOM API:

  • JavaScript thuần không có pseudo-selectors tích hợp sẵn để chọn các phần tử theo trạng thái (ví dụ: :checked, :disabled, :visible).

  • Nếu muốn kiểm tra các trạng thái này, bạn cần phải làm thủ công, ví dụ như kiểm tra thuộc tính checked cho checkbox hoặc disabled cho input.

jQuery:

  • jQuery cung cấp các pseudo-selectors tích hợp sẵn để dễ dàng chọn các phần tử theo trạng thái như :checked, :disabled, :visible, :hidden, v.v.

  • Ví dụ:

$('input:checked');  // Chọn tất cả các input được chọn (checkbox hoặc radio)
$('div:visible');    // Chọn tất cả các div đang hiển thị

So sánh:

  • jQuery có lợi thế vượt trội vì hỗ trợ sẵn các pseudo-selectors, giúp việc chọn phần tử theo trạng thái trở nên đơn giản và trực quan hơn nhiều.

Hiệu suất

  • JavaScript DOM API:

    • JavaScript thuần có hiệu suất cao hơn vì không phải tải thêm thư viện và không có sự tốn kém của việc phải gọi các hàm jQuery.

    • Tuy nhiên, khi làm việc với nhiều phần tử DOM hoặc các thao tác phức tạp, bạn có thể cần viết mã phức tạp để tối ưu hóa hiệu suất.

  • jQuery:

    • jQuery có thể chậm hơn một chút so với JavaScript thuần, vì phải tải và sử dụng thư viện jQuery, và một số phương thức của jQuery có thể tốn thời gian xử lý.

    • Tuy nhiên, đối với các tác vụ cơ bản, sự chênh lệch về hiệu suất có thể không rõ rệt, nhưng khi cần thực hiện các thao tác phức tạp hoặc với số lượng phần tử lớn, hiệu suất có thể bị ảnh hưởng.

  • So sánh:

    • JavaScript thuần cho hiệu suất cao hơn vì không phải tải thư viện và không có overhead từ các phương thức của jQuery.

    • jQuery có thể chậm hơn đôi chút nhưng lại giúp giảm bớt độ phức tạp trong việc thao tác DOM, giúp tăng năng suất lập trình viên, đặc biệt trong các dự án nhỏ và vừa.

Ứng dụng thực tế trong JavaScript

Gắn sự kiện click cho nhiều button bằng selector class

Trong JavaScript thuần và jQuery, bạn có thể dễ dàng gắn sự kiện click cho nhiều nút (button) sử dụng selector class. Điều này giúp bạn xử lý các sự kiện đồng loạt trên nhiều phần tử mà không cần phải viết nhiều lần mã giống nhau.

  • JavaScript thuần:

var buttons = document.querySelectorAll('.myButton');
buttons.forEach(function(button) {
  button.addEventListener('click', function() {
    alert('Button clicked!');
  });
});

jQuery:

$('.myButton').click(function() {
  alert('Button clicked!');
});

Cả hai ví dụ trên đều thực hiện hành động khi người dùng nhấn vào bất kỳ nút nào có class myButton. jQuery giúp mã ngắn gọn và dễ đọc hơn.

Lấy nội dung form với input[type="text"] trong jQuery

Để lấy nội dung từ một trường input trong form (chẳng hạn input[type="text"]), bạn có thể sử dụng các selectors trong jQuery. Điều này rất hữu ích khi bạn cần thu thập dữ liệu từ form mà không phải viết mã phức tạp.

  • jQuery:

var textValue = $('input[type="text"]').val();
console.log(textValue);

Lệnh trên sẽ lấy giá trị hiện tại trong trường input loại text và in ra console.

Duyệt danh sách sản phẩm và highlight sản phẩm nổi bật

Giả sử bạn có một danh sách sản phẩm và muốn duyệt qua từng sản phẩm, đồng thời làm nổi bật các sản phẩm nổi bật (ví dụ: sản phẩm có rating cao hoặc đang giảm giá). Bạn có thể sử dụng selectors để chọn tất cả các sản phẩm và áp dụng một class CSS để làm nổi bật chúng.

HTML:

<ul class="product-list">
  <li class="product" data-rating="5">Product 1</li>
  <li class="product" data-rating="3">Product 2</li>
  <li class="product" data-rating="4">Product 3</li>
  <li class="product" data-rating="5">Product 4</li>
</ul>

JavaScript thuần:

var products = document.querySelectorAll('.product');
products.forEach(function(product) {
  if (product.getAttribute('data-rating') === '5') {
    product.classList.add('highlight');
  }
});

jQuery:

$('.product').each(function() {
  if ($(this).data('rating') === 5) {
    $(this).addClass('highlight');
  }
});

Cả hai cách đều làm nổi bật sản phẩm có rating 5 sao. Với jQuery, cú pháp ngắn gọn hơn và dễ đọc hơn rất nhiều.

Lưu ýkhi sử dụng selectors trong JavaScript

Khi sử dụng selectors trong JavaScript hoặc jQuery, có một số lưu ý quan trọng để tối ưu hóa hiệu suất và đảm bảo mã của bạn hoạt động một cách hiệu quả.

Tối ưu hiệu suất bằng cách hạn chế selector phức tạp

Các selectors phức tạp (chẳng hạn như .class1 > .class2 .class3) có thể làm giảm hiệu suất của trang web, đặc biệt khi bạn làm việc với nhiều phần tử DOM. Mỗi lần bạn sử dụng một selector phức tạp, trình duyệt cần duyệt qua toàn bộ DOM để tìm kiếm các phần tử phù hợp, điều này có thể ảnh hưởng đến tốc độ render của trang.

Lời khuyên: Sử dụng các selectors đơn giản, cụ thể, và tránh lặp lại các phần tử DOM không cần thiết.

Ví dụ:

// Thay vì dùng selector phức tạp, hãy chọn trực tiếp theo ID hoặc class cụ thể
var element = document.querySelector('#myDiv');

Không lạm dụng selector động quá nhiều (ảnh hưởng hiệu năng)

Việc sử dụng selectors động (selectors được tạo ra trong thời gian thực, chẳng hạn như .find(), $(this), .parent(), v.v.) có thể gây ảnh hưởng đến hiệu suất nếu thực hiện quá nhiều lần trong vòng lặp hoặc trong các sự kiện.

Ví dụ:

// Lạm dụng `.find()` trong vòng lặp
$('.container').each(function() {
  $(this).find('.child');
});

Cách làm trên sẽ khiến việc tìm kiếm phần tử .child trong .container trở nên chậm nếu có quá nhiều phần tử DOM cần duyệt. Thay vào đó, hãy giảm thiểu số lần gọi các phương thức như .find() trong vòng lặp.

Đảm bảo DOM đã được load (dùng DOMContentLoaded hoặc $(document).ready())

Khi sử dụng selectors trong JavaScript hoặc jQuery, hãy đảm bảo rằng DOM đã được tải trước khi truy xuất các phần tử. Nếu bạn thực hiện truy vấn DOM trước khi trang tải xong, có thể gây lỗi hoặc không tìm được phần tử vì nó chưa có trong DOM.

JavaScript thuần:

document.addEventListener('DOMContentLoaded', function() {
  var element = document.querySelector('#myDiv');
  console.log(element);
});

jQuery:

$(document).ready(function() {
  var element = $('#myDiv');
  console.log(element);
});

Cả hai phương pháp này giúp đảm bảo rằng các thao tác với DOM sẽ chỉ được thực hiện khi trang đã sẵn sàng.

Kết bài

Trong quá trình phát triển web, việc sử dụng selectors để truy xuất phần tử DOM là một phần không thể thiếu. Với JavaScript thuầnjQuery, việc hiểu và sử dụng đúng các selectors sẽ giúp tối ưu hóa hiệu suất, đơn giản hóa mã nguồn và cải thiện trải nghiệm người dùng. Bằng cách sử dụng các phương thức như getElementById(), querySelector(), hoặc các selectors trong jQuery như $('.class'), chúng ta có thể dễ dàng tương tác với các phần tử trong DOM để thực hiện các thao tác như gắn sự kiện, thay đổi nội dung hoặc áp dụng các hiệu ứng.

Tuy nhiên, cũng cần lưu ý rằng việc lạm dụng selectors phức tạp và động có thể gây ảnh hưởng đến hiệu suất của ứng dụng, đặc biệt khi làm việc với các DOM lớn. Việc đảm bảo rằng DOM đã được tải xong và tối ưu hóa các selector sẽ giúp đảm bảo ứng dụng của bạn hoạt động mượt mà và hiệu quả.

Cuối cùng, việc lựa chọn sử dụng JavaScript thuần hay jQuery tùy thuộc vào yêu cầu của dự án và nhu cầu cụ thể của bạn. Cả hai đều mạnh mẽ và có thể đáp ứng tốt các yêu cầu truy xuất phần tử DOM, nhưng jQuery mang lại sự đơn giản và dễ dàng hơn cho người mới bắt đầu.

Bài viết liên quan