jQuery DOM: Cách thao tác HTML, CSS, Class, Attribute và phần tử

DOM là phần nền tảng giúp JavaScript tương tác trực tiếp với nội dung đang hiển thị trên trang web. Khi sử dụng jQuery, việc làm việc với DOM trở nên ngắn gọn hơn nhờ hệ thống selector và các phương thức được thiết kế để tìm, đọc, thay đổi hoặc quản lý phần tử HTML. Đây cũng là nhóm chức năng xuất hiện rất thường xuyên khi xây dựng giao diện có tương tác.

Thay vì thao tác với từng API DOM nguyên bản bằng nhiều dòng JavaScript, jQuery cho phép xử lý phần tử theo cách nhất quán: chọn đối tượng cần tác động, gọi phương thức tương ứng và tiếp tục kết hợp nhiều thao tác trong cùng một chuỗi. Tuy nhiên, để sử dụng hiệu quả, cần phân biệt rõ việc đọc dữ liệu, thay đổi dữ liệu, thay đổi giao diệnthay đổi cấu trúc phần tử.

jQuery DOM: Cách thao tác HTML, CSS, Class, Attribute và phần tử
jQuery DOM: Cách thao tác HTML, CSS, Class, Attribute và phần tử

DOM trong jQuery hoạt động như thế nào?

DOM có thể hiểu là mô hình biểu diễn tài liệu HTML dưới dạng một cấu trúc cây. Mỗi phần tử như div, p, a hay input trở thành một node mà JavaScript có thể truy cập và xử lý.

jQuery không thay thế DOM. Nó cung cấp một lớp API thuận tiện để tìm và thao tác với các phần tử DOM. Khi viết một biểu thức như $('#content'), jQuery sẽ tìm phần tử có id tương ứng rồi tạo ra một đối tượng jQuery chứa kết quả tìm được.

Điểm quan trọng là selector và phương thức thao tác là hai vấn đề khác nhau. Selector quyết định phần tử nào được chọn, còn phương thức quyết định phần tử đó sẽ được xử lý ra sao.

const box = $('#content');
box.text('Nội dung mới');

Trong ví dụ trên, #content dùng để xác định phần tử, còn text() thay đổi nội dung văn bản của phần tử đó. Cách tư duy này giúp code dễ đọc hơn và cũng dễ mở rộng khi cần xử lý nhiều phần tử.

Chọn một hoặc nhiều phần tử

jQuery hỗ trợ các selector CSS quen thuộc nên có thể chọn phần tử theo id, class, tên thẻ, thuộc tính hoặc sự kết hợp giữa nhiều điều kiện.

$('#menu');
$('.product');
$('p');
$('input[name="email"]');
$('.menu li.active');

Một selector có thể trả về một hoặc nhiều phần tử. Nếu selector khớp với nhiều phần tử, các phương thức thao tác phù hợp của jQuery thường được áp dụng cho toàn bộ tập phần tử đó.

Điều này đặc biệt hữu ích khi cần cập nhật một nhóm phần tử có cùng đặc điểm thay vì phải viết vòng lặp thủ công cho từng node.

Đọc và thay đổi nội dung phần tử

Ba phương thức thường gặp nhất khi làm việc với nội dung là text(), html()val(). Mặc dù đều liên quan đến dữ liệu hiển thị hoặc giá trị bên trong phần tử, chúng có mục đích khác nhau.

Dùng text() với nội dung văn bản

text() dùng để lấy hoặc thiết lập nội dung dạng văn bản. Khi truyền một giá trị vào phương thức, jQuery sẽ thay thế nội dung văn bản của phần tử.

const title = $('#title').text();

$('#title').text('Tiêu đề mới');

Khi dùng để đọc dữ liệu, text() phù hợp với trường hợp chỉ quan tâm đến nội dung chữ và không muốn xử lý các thẻ HTML bên trong.

Đây cũng là lựa chọn an toàn hơn khi dữ liệu đến từ người dùng hoặc một nguồn không hoàn toàn đáng tin cậy, bởi dữ liệu được xem như văn bản thay vì được diễn giải thành HTML.

Dùng html() khi cần thao tác nội dung HTML

html() cho phép đọc hoặc thay thế phần HTML nằm bên trong phần tử được chọn.

const content = $('#content').html();

$('#content').html('<p>Nội dung mới</p>');

Khác với text(), nội dung truyền vào html() có thể được trình duyệt phân tích thành cấu trúc HTML. Vì vậy, phương thức này cần được sử dụng cẩn thận khi dữ liệu có nguồn từ người dùng hoặc hệ thống bên ngoài.

Nếu mục tiêu chỉ là hiển thị một chuỗi văn bản, nên ưu tiên text(). Chỉ sử dụng html() khi thực sự cần tạo hoặc thay thế markup.

Lấy giá trị của biểu mẫu bằng val()

Đối với các phần tử biểu mẫu như input, selecttextarea, val() là phương thức phù hợp để đọc hoặc thay đổi giá trị.

const email = $('#email').val();

$('#email').val('contact@example.com');

Điểm cần nhớ là val() xử lý giá trị của form control, trong khi text() xử lý nội dung văn bản của phần tử. Hai phương thức này không nên được xem là có thể thay thế cho nhau.

Thay đổi nội dung theo dữ liệu động

Trong ứng dụng thực tế, nội dung hiếm khi cố định. Một phần tử có thể cần hiển thị tên người dùng, trạng thái đơn hàng, số lượng sản phẩm hoặc thông báo được lấy từ một thao tác trước đó.

jQuery cho phép truyền hàm vào một số phương thức để tính nội dung mới dựa trên giá trị hiện tại. Cách này hữu ích khi giá trị mới phụ thuộc vào dữ liệu đang có trong phần tử.

$('.item').text(function(index, currentText) {
    return 'Mục ' + (index + 1) + ': ' + currentText;
});

Thay vì đọc toàn bộ phần tử trước rồi tạo một vòng lặp riêng, thao tác có thể được đặt trực tiếp trong phương thức. Với các xử lý đơn giản, cách viết này giúp mối quan hệ giữa phần tử và dữ liệu cần cập nhật rõ ràng hơn.

Thêm hoặc thay thế nội dung trong cấu trúc DOM

Thay đổi nội dung bên trong một phần tử chỉ là một phần của việc thao tác DOM. Khi xây dựng giao diện động, thường cần thêm node mới vào đầu, cuối hoặc thay thế một phần tử hiện có.

Thêm nội dung vào cuối bằng append()

append() thêm nội dung vào phía cuối phần tử được chọn.

$('#list').append('<li>Phần tử mới</li>');

Nếu phần tử #list đã chứa nhiều node con, nội dung mới sẽ được đưa xuống sau các node hiện có. Đây là cách thường dùng khi cần bổ sung một dòng dữ liệu, một mục danh sách hoặc một thành phần giao diện mới.

Thêm nội dung vào đầu bằng prepend()

prepend() có tác dụng ngược với append(): nội dung mới được đưa lên trước các node con hiện tại.

$('#list').prepend('<li>Phần tử mới nhất</li>');

Việc chọn append() hay prepend() phụ thuộc vào thứ tự mà giao diện yêu cầu. Với danh sách dữ liệu mới nhất nằm trên cùng, prepend() thường phù hợp hơn.

Chèn phần tử bên ngoài bằng before() và after()

Nếu cần đưa một phần tử mới đứng trước hoặc sau phần tử đang chọn, có thể sử dụng before()after().

$('#title').before('<p>Nội dung phía trước</p>');

$('#title').after('<p>Nội dung phía sau</p>');

Khác biệt quan trọng là append()prepend() tác động vào bên trong phần tử, còn before()after() chèn node ở vị trí ngang hàng với phần tử đó.

Thay thế phần tử bằng replaceWith()

Khi không muốn giữ phần tử cũ mà cần đưa một phần tử khác vào đúng vị trí của nó, replaceWith() là phương thức phù hợp.

$('#old-box').replaceWith('<div id="new-box">Nội dung mới</div>');

Cách này hữu ích khi trạng thái giao diện thay đổi hoàn toàn. Thay vì xóa node rồi thêm một node khác ở vị trí tương ứng, có thể thể hiện trực tiếp ý định thay thế trong code.

Điều khiển giao diện bằng CSS

Trong các giao diện có tương tác, thay đổi nội dung thường đi cùng với thay đổi cách hiển thị. jQuery cung cấp css() để đọc hoặc thiết lập giá trị CSS cho phần tử mà không cần thao tác trực tiếp với thuộc tính style bằng JavaScript thuần.

Với những thay đổi đơn giản như chiều cao, chiều rộng, khoảng cách hoặc trạng thái hiển thị, css() có thể giải quyết nhanh chóng. Tuy nhiên, không nên biến phương thức này thành cách xây dựng toàn bộ giao diện bằng JavaScript. Những trạng thái có tính hệ thống thường nên được quản lý bằng class để CSS đảm nhận phần trình bày.

Đọc giá trị CSS hiện tại

Khi gọi css() với tên thuộc tính và không truyền giá trị thứ hai, jQuery sẽ đọc giá trị CSS của phần tử.

const width = $('#box').css('width');
const color = $('#box').css('color');

Cách này phù hợp khi một thao tác JavaScript cần biết trạng thái hiện tại của giao diện trước khi quyết định bước tiếp theo. Tuy nhiên, giá trị nhận được có thể phụ thuộc vào cách trình duyệt tính toán style nên không nên mặc định xem nó luôn là giá trị nguyên bản được viết trong file CSS.

Thiết lập một thuộc tính CSS

Truyền thêm giá trị vào css() sẽ tạo hoặc thay đổi style cho phần tử.

$('#box').css('color', '#D3801F');
$('#box').css('margin-top', '20px');

jQuery cũng cho phép truyền một object để thay đổi nhiều thuộc tính trong cùng một lần gọi.

$('#box').css({
    width: '300px',
    padding: '20px',
    border: '1px solid #ddd'
});

Cách viết object đặc biệt hữu ích khi một hành động cần cập nhật nhiều thông số giao diện cùng lúc. Nó cũng giúp tránh việc gọi css() lặp lại quá nhiều lần cho cùng một phần tử.

Thay đổi CSS dựa trên trạng thái hiện tại

Khi giá trị mới phụ thuộc vào giá trị đang có, có thể truyền một hàm vào css().

$('.box').css('font-size', function(index, currentValue) {
    return currentValue;
});

Trong thực tế, cách này phù hợp hơn với những phép biến đổi có quy tắc rõ ràng. Nếu trạng thái chỉ đơn giản là bật hoặc tắt một kiểu hiển thị, sử dụng class thường dễ bảo trì hơn.

Quản lý class để tạo trạng thái giao diện

Class là một trong những công cụ quan trọng nhất khi kết hợp jQuery với CSS. Thay vì đặt hàng loạt thuộc tính CSS trực tiếp từ JavaScript, có thể để CSS định nghĩa trạng thái rồi dùng jQuery thêm hoặc xóa class khi trạng thái thay đổi.

Cách tiếp cận này tạo ra sự phân tách rõ ràng: jQuery xử lý hành vi, còn CSS xử lý cách hiển thị. Khi thiết kế thay đổi, phần CSS có thể được chỉnh sửa mà không phải viết lại logic JavaScript.

Thêm class bằng addClass()

addClass() thêm một hoặc nhiều class vào phần tử đang được chọn.

$('#menu').addClass('active');

Nếu phần tử đã có class đó, jQuery không cần tạo thêm một bản sao. Vì vậy, phương thức này phù hợp khi một thao tác chỉ có nhiệm vụ đưa phần tử vào một trạng thái cụ thể.

Có thể thêm nhiều class trong một lần gọi:

$('#menu').addClass('active highlighted');

Xóa class bằng removeClass()

removeClass() loại bỏ class khỏi phần tử.

$('#menu').removeClass('active');

Đây là cách phổ biến để đưa giao diện trở lại trạng thái ban đầu sau khi một hành động kết thúc. Khi cần loại bỏ nhiều class, có thể truyền danh sách class tương ứng.

$('#menu').removeClass('active highlighted');

Kiểm tra class với hasClass()

hasClass() trả về giá trị Boolean cho biết phần tử có chứa class được kiểm tra hay không.

if ($('#menu').hasClass('active')) {
    console.log('Menu đang được kích hoạt');
}

Phương thức này đặc biệt hữu ích khi logic tiếp theo phụ thuộc vào trạng thái hiện tại của phần tử. Thay vì đoán trạng thái từ giao diện, JavaScript có thể kiểm tra trực tiếp class đang tồn tại.

Đảo trạng thái bằng toggleClass()

toggleClass() cho phép chuyển đổi qua lại giữa hai trạng thái: nếu class chưa tồn tại thì thêm vào, nếu đã tồn tại thì loại bỏ.

$('#menu').toggleClass('active');

Đây là phương thức rất phù hợp với các thành phần có trạng thái bật và tắt. Một nút mở rộng nội dung, một menu thu gọn hoặc một vùng được đánh dấu đều có thể sử dụng cách này.

Tuy nhiên, toggle không phải lúc nào cũng là lựa chọn tốt nhất. Nếu trạng thái giao diện phải phụ thuộc vào một điều kiện cụ thể từ dữ liệu, việc gọi addClass() hoặc removeClass() một cách rõ ràng có thể giúp logic dễ đọc và ít gây nhầm lẫn hơn.

Đọc và thay đổi thuộc tính HTML

Attribute là dữ liệu được khai báo trực tiếp trên thẻ HTML, chẳng hạn id, class, href, src, title hoặc các thuộc tính data-*. jQuery cung cấp attr() để đọc và thay đổi những giá trị này.

Lấy giá trị attribute bằng attr()

Để đọc một thuộc tính, truyền tên attribute vào attr().

const link = $('#website').attr('href');
const image = $('#banner').attr('src');

Cách này thường được sử dụng khi cần lấy URL của liên kết, nguồn hình ảnh hoặc một giá trị cấu hình được đặt trực tiếp trên phần tử.

Thiết lập attribute

Truyền thêm giá trị thứ hai sẽ thay đổi attribute tương ứng.

$('#website').attr('href', 'https://example.com');
$('#banner').attr('title', 'Ảnh giới thiệu');

Nếu cần thay đổi nhiều attribute, có thể truyền một object.

$('#website').attr({
    href: 'https://example.com',
    title: 'Truy cập website'
});

Cách này giúp gom các thay đổi thuộc cùng một phần tử vào một khối logic duy nhất, đặc biệt hữu ích khi tạo hoặc cập nhật thành phần giao diện động.

Xóa attribute bằng removeAttr()

Khi một thuộc tính không còn cần thiết, có thể dùng removeAttr() để loại bỏ nó khỏi phần tử.

$('#website').removeAttr('title');

Việc xóa attribute khác với việc đặt giá trị rỗng. Hai cách này có thể tạo ra hành vi khác nhau tùy thuộc vào thuộc tính và cách trình duyệt xử lý nó. Vì vậy, nếu mục tiêu thực sự là loại bỏ thuộc tính khỏi HTML, removeAttr() thể hiện ý định rõ ràng hơn.

Phân biệt attr(), prop() và dữ liệu của phần tử

Một trong những điểm dễ gây nhầm lẫn khi thao tác DOM là coi mọi thông tin của phần tử đều là attribute. Trên thực tế, một số trạng thái của phần tử được trình duyệt quản lý dưới dạng property.

jQuery cung cấp prop() cho những trường hợp cần làm việc với property của DOM object. Sự khác biệt này đặc biệt quan trọng với các phần tử biểu mẫu.

Property và attribute không phải lúc nào cũng giống nhau

Ví dụ, trạng thái được chọn của một checkbox có thể thay đổi trong quá trình người dùng tương tác, trong khi attribute ban đầu trong HTML không nhất thiết thay đổi theo.

const checked = $('#agree').prop('checked');

$('#agree').prop('checked', true);

Ở đây, prop() phù hợp để đọc hoặc thiết lập trạng thái hiện tại của checkbox. Đây là một ví dụ điển hình cho việc cần hiểu bản chất dữ liệu trước khi chọn phương thức.

Khi nào nên dùng attr() và khi nào nên dùng prop()?

Trường hợp Phương thức phù hợp Mục đích
Đọc href, src, title attr() Thao tác với attribute HTML
Đọc trạng thái checkbox prop() Lấy property hiện tại của DOM
Thiết lập checked prop() Thay đổi trạng thái hiện tại
Xóa attribute removeAttr() Loại bỏ attribute khỏi phần tử

Không nên lựa chọn phương thức chỉ dựa trên tên thuộc tính. Hãy xác định trước rằng mình đang muốn thay đổi markup hay trạng thái thực tế mà DOM đang quản lý.

Tạo, sao chép và xóa phần tử

jQuery không chỉ thay đổi những node đã tồn tại mà còn có thể tạo, sao chép, di chuyển và xóa phần tử. Đây là nhóm thao tác quan trọng khi xây dựng danh sách hoặc thành phần giao diện được sinh từ dữ liệu.

Tạo phần tử mới

Có thể truyền chuỗi HTML vào jQuery để tạo một phần tử mới.

const item = $('<li>Mục mới</li>');

$('#list').append(item);

Cách này giúp tách bước tạo node khỏi bước đưa node vào DOM. Khi logic phức tạp hơn, việc tạo phần tử trước rồi mới thiết lập thuộc tính, class hoặc nội dung sẽ dễ kiểm soát hơn.

Sao chép phần tử bằng clone()

clone() tạo bản sao của phần tử đang chọn.

const copy = $('#item').clone();

$('#list').append(copy);

Thao tác này hữu ích khi một giao diện có mẫu phần tử giống nhau và cần tạo thêm bản sao. Tuy nhiên, khi sao chép thành phần có trạng thái hoặc sự kiện tương tác, cần xem xét kỹ dữ liệu và event đi kèm thay vì mặc định rằng mọi hành vi của phần tử gốc sẽ luôn được sao chép theo đúng mong muốn.

Xóa phần tử bằng remove()

remove() loại bỏ phần tử được chọn khỏi DOM.

$('#temporary-box').remove();

Nếu phần tử không còn cần thiết, xóa nó khỏi DOM giúp cấu trúc tài liệu gọn hơn. Đây là thao tác thường gặp khi đóng thông báo, xóa một dòng dữ liệu hoặc loại bỏ thành phần giao diện tạm thời.

Làm rỗng phần tử bằng empty()

empty() khác với remove(). Nó giữ lại phần tử hiện tại nhưng xóa toàn bộ nội dung con bên trong.

$('#list').empty();

Ví dụ, sau khi người dùng thay đổi bộ lọc, có thể làm rỗng danh sách cũ rồi đưa các kết quả mới vào. Trong trường hợp này, xóa chính container bằng remove() sẽ không phù hợp vì container vẫn cần được sử dụng.

Duyệt và thao tác từng phần tử

Khi selector trả về nhiều phần tử, jQuery có thể áp dụng nhiều phương thức trực tiếp lên toàn bộ tập kết quả. Tuy nhiên, có những tình huống mỗi phần tử cần một giá trị khác nhau. Khi đó, each() là công cụ phù hợp để xử lý từng node riêng biệt.

Áp dụng cùng một thay đổi cho nhiều phần tử

Không phải lúc nào cũng cần dùng vòng lặp. Nếu tất cả phần tử được chọn cần cùng một thay đổi, jQuery có thể tự thực hiện thao tác trên tập phần tử.

$('.notice').addClass('visible');

Đoạn code trên áp dụng class cho toàn bộ phần tử có class notice. Đây là một trong những ưu điểm đáng chú ý của jQuery: nhiều thao tác DOM có thể thực hiện trên một tập phần tử mà không cần viết vòng lặp thủ công.

Xử lý từng node với each()

Khi mỗi phần tử cần xử lý theo dữ liệu riêng, có thể dùng each().

$('.product').each(function(index) {
    const name = $(this).find('.name').text();

    console.log(index, name);
});

Bên trong callback, this đại diện cho phần tử DOM hiện tại. Có thể chuyển nó thành đối tượng jQuery bằng cách sử dụng $(this), sau đó tiếp tục gọi các phương thức như find(), text(), attr() hoặc addClass().

Tìm phần tử con và phần tử liên quan

Trong giao diện thực tế, selector ban đầu thường chỉ xác định một vùng lớn. Sau đó cần tìm các phần tử nằm bên trong vùng đó hoặc tìm một node có quan hệ với node hiện tại.

Tìm phần tử bên trong bằng find()

find() tìm các phần tử hậu duệ bên trong phần tử hiện tại.

$('#product').find('.price').text('500.000đ');

Cách viết này đặc biệt hữu ích khi trang có nhiều phần tử cùng class nhưng chỉ muốn thao tác với phần tử thuộc một container cụ thể. Thay vì tìm trên toàn bộ document, phạm vi tìm kiếm được giới hạn từ node cha.

Lấy phần tử cha bằng parent()

parent() lấy phần tử cha trực tiếp của node đang chọn.

$('.price').parent().addClass('has-price');

Khi cần đi lên nhiều cấp trong cấu trúc DOM, có thể sử dụng những phương thức phù hợp với quan hệ giữa các node thay vì dựa vào selector toàn trang.

Tìm phần tử gần nhất bằng closest()

closest() tìm phần tử gần nhất từ node hiện tại đi ngược lên cây DOM dựa trên selector được cung cấp.

$('.delete-button').closest('.item').addClass('removing');

Đây là phương thức rất hữu ích với giao diện có cấu trúc lặp lại. Một nút bên trong từng dòng dữ liệu có thể xác định chính xác container của nó mà không cần biết dòng đó đang đứng ở vị trí thứ bao nhiêu.

Làm việc với dữ liệu data-*

HTML hỗ trợ các thuộc tính tùy biến bắt đầu bằng data- để gắn dữ liệu vào phần tử. jQuery cung cấp data() nhằm đọc và quản lý loại dữ liệu này thuận tiện hơn.

const id = $('#product').data('id');

Với HTML có thuộc tính data-id, jQuery có thể lấy giá trị thông qua tên id. Điều này giúp giao diện giữ một mã định danh cần thiết cho JavaScript mà không phải tạo thêm nhiều biến hoặc cấu trúc dữ liệu riêng.

Có thể thiết lập dữ liệu bằng:

$('#product').data('id', 25);

Tuy nhiên, cần phân biệt giữa dữ liệu được jQuery quản lý thông qua data() và attribute data-* thực sự tồn tại trong HTML. Nếu yêu cầu là thay đổi markup để có thể quan sát trực tiếp attribute, attr() mới là phương thức cần xem xét.

Kết hợp nhiều thao tác trong một luồng xử lý

Sức mạnh của jQuery DOM không chỉ nằm ở từng phương thức riêng lẻ mà còn ở khả năng kết hợp chúng thành một quy trình ngắn gọn. Một thao tác có thể bắt đầu từ phần tử được chọn, tìm node con, cập nhật nội dung, thêm class và thay đổi attribute.

const item = $('#product');

item.find('.name').text('Sản phẩm mới');
item.find('.price').text('750.000đ');
item.addClass('updated');
item.attr('data-status', 'available');

Cách tổ chức này dễ đọc vì mỗi bước có một nhiệm vụ rõ ràng. Khi xử lý phức tạp hơn, nên ưu tiên đặt các bước theo đúng trình tự nghiệp vụ thay vì cố gắng viết tất cả thành một chuỗi phương thức quá dài.

Khi nào nên chain phương thức?

jQuery hỗ trợ chaining, nghĩa là có thể tiếp tục gọi phương thức trên kết quả của phương thức trước.

$('#title')
    .addClass('active')
    .text('Tiêu đề mới');

Chaining phù hợp khi các thao tác liên quan trực tiếp đến cùng một đối tượng và trình tự thực hiện dễ hiểu. Nó giúp giảm biến trung gian và làm code ngắn hơn.

Tuy nhiên, không nên ép mọi đoạn xử lý thành một chuỗi dài. Khi mỗi bước có điều kiện khác nhau hoặc cần kiểm tra dữ liệu, tách thành nhiều câu lệnh thường dễ đọc và dễ debug hơn.

Thực hiện thay đổi DOM từ dữ liệu động

Một tình huống phổ biến là nhận dữ liệu rồi xây dựng giao diện tương ứng. Ví dụ, sau khi có danh sách kết quả, JavaScript có thể làm rỗng container cũ và tạo các mục mới.

const products = [
    { name: 'Sản phẩm A', price: '300.000đ' },
    { name: 'Sản phẩm B', price: '450.000đ' }
];

const list = $('#product-list');

list.empty();

products.forEach(function(product) {
    const item = $('<li>');
    item.text(product.name + ' - ' + product.price);
    list.append(item);
});

Điểm đáng chú ý trong ví dụ là dữ liệu và cấu trúc giao diện được xử lý theo từng bước. Container cũ được làm rỗng, mỗi bản ghi tạo ra một node mới rồi node đó được đưa vào danh sách.

Với dữ liệu thực tế, cần đặc biệt chú ý đến nguồn dữ liệu trước khi đưa nó vào HTML. Nếu dữ liệu có thể chứa nội dung do người dùng nhập, việc sử dụng text() thay vì ghép trực tiếp thành HTML thường là lựa chọn an toàn hơn.

Những lỗi thường gặp khi thao tác DOM

Nhầm giữa nội dung văn bản và HTML

Một lỗi phổ biến là sử dụng html() trong mọi trường hợp chỉ vì muốn thay đổi nội dung. Nếu dữ liệu chỉ là chữ, text() thường phù hợp hơn.

$('#message').text(userMessage);

Cách này giúp chuỗi dữ liệu được xử lý như văn bản thay vì trở thành một phần của cấu trúc HTML.

Lạm dụng css() cho mọi trạng thái

Đặt trực tiếp hàng loạt style từ JavaScript có thể khiến logic giao diện khó bảo trì. Nếu một thành phần có trạng thái như mở, đóng, đang chọn hoặc bị vô hiệu hóa, nên cân nhắc tạo class tương ứng rồi dùng jQuery để bật hoặc tắt class.

$('#panel').addClass('open');
$('#panel').removeClass('open');

Như vậy, JavaScript chỉ cần quan tâm đến trạng thái còn CSS quyết định trạng thái đó được hiển thị như thế nào.

Chọn selector quá rộng

Selector càng rộng thì càng dễ tác động nhầm đến những phần tử không liên quan. Ví dụ, nếu một trang có nhiều nút dùng chung một class, việc thay đổi toàn bộ chúng chỉ vì một thao tác cụ thể có thể tạo ra lỗi giao diện khó phát hiện.

Nên giới hạn phạm vi bằng container hoặc selector có ngữ cảnh rõ ràng.

$('#cart').find('.remove').addClass('disabled');

Cách này rõ ràng hơn so với việc tác động đến toàn bộ phần tử có class remove trên trang.

Thao tác DOM quá nhiều lần

Khi xây dựng một danh sách lớn, việc liên tục sửa DOM trong từng bước có thể tạo ra nhiều lần cập nhật giao diện không cần thiết. Với lượng dữ liệu nhỏ, sự khác biệt có thể không đáng kể, nhưng khi số lượng node tăng lên, cách xây dựng giao diện cần được cân nhắc kỹ hơn.

Một nguyên tắc thực tế là chuẩn bị dữ liệu và cấu trúc cần thiết trước, sau đó thực hiện các thay đổi DOM theo từng nhóm hợp lý thay vì liên tục đọc rồi ghi vào giao diện sau mỗi thao tác nhỏ.

Cách tổ chức code jQuery DOM dễ bảo trì

Code thao tác DOM nên thể hiện rõ ba vấn đề: phần tử nào được tác động, trạng thái nào cần thay đổithay đổi đó phục vụ mục đích gì. Khi ba yếu tố này bị trộn lẫn trong một đoạn code quá dài, việc sửa lỗi hoặc mở rộng chức năng sẽ khó hơn.

Nên đặt selector có ý nghĩa, tránh lặp lại cùng một selector nhiều lần nếu phần tử được sử dụng trong nhiều thao tác.

const panel = $('#panel');

panel.find('.title').text('Thông tin mới');
panel.addClass('updated');
panel.attr('aria-label', 'Nội dung đã cập nhật');

Với những thao tác lặp lại, có thể đóng gói thành hàm riêng thay vì sao chép cùng một nhóm lệnh ở nhiều vị trí.

function updatePanel(title) {
    const panel = $('#panel');

    panel.find('.title').text(title);
    panel.addClass('updated');
}

Cách tổ chức này giúp phần xử lý giao diện có một nơi chịu trách nhiệm rõ ràng. Khi yêu cầu thay đổi, chỉ cần điều chỉnh logic tại vị trí đó thay vì tìm và sửa nhiều đoạn code giống nhau.

Tư duy đúng khi sử dụng jQuery để thao tác giao diện

Điểm quan trọng nhất khi làm việc với DOM không phải là ghi nhớ thật nhiều phương thức mà là hiểu đúng loại thay đổi cần thực hiện. Nếu muốn đổi chữ, hãy nghĩ đến text(). Nếu cần HTML thực sự, cân nhắc html(). Nếu muốn thay đổi trạng thái trình bày, ưu tiên class. Nếu cần làm việc với attribute, dùng attr(). Nếu đang xử lý property của DOM như trạng thái checkbox, prop() thường là lựa chọn phù hợp hơn.

Nhu cầu Phương thức nên xem xét Vai trò
Đọc hoặc thay đổi chữ text() Xử lý nội dung văn bản
Đọc hoặc tạo markup html() Xử lý nội dung HTML
Giá trị form val() Đọc và thay đổi value
Thay đổi giao diện addClass(), removeClass(), toggleClass() Quản lý trạng thái bằng class
Đọc hoặc thay đổi attribute attr() Quản lý thuộc tính HTML
Thay đổi property DOM prop() Quản lý trạng thái hiện tại của DOM
Tạo hoặc loại bỏ node append(), prepend(), remove(), empty() Quản lý cấu trúc phần tử
Tìm node liên quan find(), parent(), closest() Di chuyển trong cây DOM

Khi nắm được sự khác nhau này, việc viết jQuery sẽ trở nên có chủ đích hơn. Thay vì thử nhiều phương thức cho đến khi giao diện hoạt động, có thể xác định loại dữ liệu hoặc trạng thái cần thay đổi rồi chọn API phù hợp ngay từ đầu.

jQuery DOM vì thế không đơn thuần là tập hợp các hàm để sửa HTML. Nó là cách tổ chức quá trình tương tác giữa JavaScript và giao diện: xác định đúng phần tử, thay đổi đúng loại dữ liệu, quản lý trạng thái hợp lý và hạn chế những cập nhật DOM không cần thiết. Đây là nền tảng quan trọng để xây dựng các thành phần tương tác mà code vẫn dễ đọc, dễ sửa và có thể mở rộng về sau.

  • 0 Bình luận
CEO Bùi Tấn Lực | Founder Web Mới
Bùi Tấn Lực
Tìm hiểu về CEO Bùi Tấn Lực, Founder Web Mới với nhiều năm kinh nghiệm trong lĩnh vực phát triển website, SEO và chia sẻ kiến thức công nghệ
Đánh giá
Chia sẻ nội dung đánh giá của bạn về jQuery DOM: Cách thao tác HTML, CSS, Class, Attribute và phần tử
Email, Điện thoại của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *
Đánh giá của bạn
Tên *
Email
Số điện thoại *
Bình luận, Hỏi đáp
Yêu Cầu Báo Giá
Gửi trang web mẫu cần làm theo, chúng tôi sẽ báo giá đến bạn từ Email (tanlucit09@gmail.com - Bùi Tấn Lực) hoặc Zalo (Lực IT - 0398259259) !