Trong hướng dẫn trước trong loạt bài này, "Cách thay đổi DOM," chúng tôi đã trình bày cách tạo, chèn, thay thế và loại bỏ các phần tử từ Mô hình đối tượng tài liệu (DOM) bằng các phương thức dựng sẵn. Bằng cách tăng trình độ của bạn trong việc thao tác DOM, bạn có thể sử dụng các khả năng tương tác và sửa đổi các yếu tố web của JavaScript tốt hơn

Trong hướng dẫn này, chúng ta sẽ tìm hiểu cách thay đổi thêm DOM bằng cách sửa đổi các  styles, classes,và  attributes khác của các nút phần tử HTML. Điều này sẽ giúp bạn hiểu rõ hơn về cách thao tác các thành phần thiết yếu trong DOM.

Xem lại các yếu tố lựa chọn

Cho đến gần đây, một thư viện JavaScript phổ biến được gọi là jQuery thường được sử dụng để chọn và sửa đổi các phần tử trong DOM. jQuery đã đơn giản hóa quy trình chọn một hoặc nhiều thành phần và áp dụng các thay đổi cho tất cả chúng cùng một lúc. Trong "Cách truy cập các phần tử trong DOM," chúng tôi đã xem xét các phương thức DOM để lấy và làm việc với các nút trong JavaScript vanilla. Để xem lại, document.querySelector () và document.getElementById () là các phương thức được sử dụng để truy cập một phần tử duy nhất. Sử dụng một div có thuộc tính id trong ví dụ bên dưới, chúng ta có thể truy cập phần tử đó theo cách nào đó.
<div id="demo-id">Demo ID</div>
Phương thức querySelector () mạnh mẽ hơn ở chỗ nó có thể chọn một phần tử trên trang theo bất kỳ kiểu chọn nào.
// Both methods will return a single element
const demoId = document.querySelector('#demo-id');

Truy cập một phần tử duy nhất, chúng ta có thể dễ dàng cập nhật một phần của phần tử như văn bản bên trong.

// Change the text of one element
demoId.textContent = 'Demo ID text updated.';
Tuy nhiên, khi truy cập nhiều phần tử bằng một bộ chọn chung, chẳng hạn như một class cụ thể, chúng ta phải lặp qua tất cả các phần tử trong list. Trong đoạn mã dưới đây, chúng ta có hai phần tử div với một giá trị class chung.
<div class="demo-class">Demo Class 1</div>
<div class="demo-class">Demo Class 2</div>
 
Chúng ta sẽ sử dụng querySelectorAll () để lấy tất cả các phần tử với demo-class được áp dụng cho chúng, và forEach () để lặp qua chúng và áp dụng một thay đổi. Cũng có thể truy cập vào một phần tử cụ thể với querySelectorAll () giống như cách bạn làm với một mảng - bằng cách sử dụng ký pháp khung.
// Get a NodeList of all .demo elements
const demoClasses = document.querySelectorAll('.demo-class');

// Change the text of multiple elements with a loop
demoClasses.forEach(element => {
  element.textContent = 'All demo classes updated.';
});

// Access the first element in the NodeList
demoClasses[0];

 Đây là một trong những sự khác biệt quan trọng nhất cần lưu ý khi phát triển từ jQuery sang JavaScript vani. Nhiều ví dụ về việc sửa đổi các phần tử sẽ không giải thích quá trình áp dụng các phương thức và thuộc tính đó cho nhiều phần tử. Các thuộc tính và phương thức trong bài viết này thường sẽ được đính kèm với trình lắng nghe sự kiện để phản hồi các nhấp chuột, trình chuyển đổi hoặc các trình kích hoạt khác.

Lưu ý: Các phương thức getElementsByClassName () và getElementsByTagName () sẽ
trả về các collection HTML mà không có quyền truy cập vào phương thức forEach ()
mà querySelectorAll () có. Trong những trường hợp này, bạn sẽ cần phải sử dụng
một tiêu chuẩn cho vòng lặp để lặp qua collection.

Sửa đổi thuộc tính

Thuộc tính là các giá trị chứa thông tin bổ sung về các phần tử HTML. Chúng thường có các cặp tên / giá trị và có thể cần thiết tùy thuộc vào phần tử. Một số thuộc tính HTML phổ biến nhất là thuộc tính src của thẻ img, href của một thẻ, class, id và style. Để biết danh sách đầy đủ các thuộc tính HTML, hãy xem danh sách thuộc tính trên Mạng nhà phát triển Mozilla. Các phần tử tùy chỉnh không phải là một phần của tiêu chuẩn HTML sẽ được thêm vào trước với dữ liệu-. Trong JavaScript, chúng tôi có bốn phương pháp để sửa đổi các thuộc tính phần tử:

Hãy tạo một tệp HTML mới với thẻ img với một thuộc tính. Chúng tôi sẽ liên kết đến một hình ảnh công khai có sẵn thông qua một URL, nhưng bạn có thể trao đổi nó ra cho một hình ảnh local thay thế nếu bạn đang làm việc ngoại tuyến.
//attributes.html
<!DOCTYPE html>
<html lang="en">
<body>

    <img src="https://js-tutorials.nyc3.digitaloceanspaces.com/shark.png">

</body>

</html>

Khi bạn tải tệp HTML ở trên vào trình duyệt web hiện đại và mở Developer Console, bạn sẽ thấy nội dung như sau:

Bây giờ, chúng ta có thể kiểm tra tất cả các phương thức thuộc tính khi đang chạy.

// Assign image element
const img = document.querySelector('img');

img.hasAttribute('src');                // returns true
img.getAttribute('src');                // returns "...shark.png"
img.removeAttribute('src');             // remove the src attribute and value

Tại thời điểm này, bạn sẽ xóa thuộc tính src và giá trị được liên kết với img, nhưng bạn có thể đặt lại thuộc tính đó và gán giá trị cho một hình ảnh thay thế bằng img.setAttribute ():

img.setAttribute('src', 'https://js-tutorials.nyc3.digitaloceanspaces.com/octopus.png');

 

 

 
Cuối cùng, chúng ta có thể sửa đổi trực tiếp thuộc tính bằng cách gán một giá trị mới cho thuộc tính làm thuộc tính của phần tử, thiết lập src trở lại tệp shark.png
img.src = 'https://js-tutorials.nyc3.digitaloceanspaces.com/shark.png';
Bất kỳ thuộc tính nào cũng có thể được chỉnh sửa theo cách này cũng như với các phương thức trên. Các phương thức hasAttribute () và getAttribute () thường được sử dụng với các câu lệnh có điều kiện và các phương thức setAttribute () và removeAttribute () được sử dụng để trực tiếp sửa đổi DOM.

Sửa đổi Classes

Thuộc tính lớp tương ứng với các bộ chọn lớp CSS. Điều này không bị nhầm lẫn với các lớp ES6, một loại hàm JavaScript đặc biệt. Các lớp CSS được sử dụng để áp dụng style cho nhiều phần tử, không giống như các ID chỉ có thể tồn tại một lần trên mỗi trang. Trong JavaScript, chúng ta có các thuộc tính className và classList để làm việc với thuộc tính class.

Chúng ta sẽ tạo một tệp HTML khác để làm việc với các phương thức class, với hai phần tử và một vài class.
classes.html
<!DOCTYPE html>
<html lang="en">

<style>
    body {
        max-width: 600px;
        margin: 0 auto;
        font-family: sans-serif;
    }
    .active {
        border: 2px solid blue;
    }

    .warning {
        border: 2px solid red;
    }

    .hidden {
        display: none;
    }

    div {
        border: 2px dashed lightgray;
        padding: 15px;
        margin: 5px;
    }
</style>

<body>

    <div>Div 1</div>
    <div class="active">Div 2</div>

</body>

</html>

Khi bạn mở tệp classes.html vào trình duyệt web, bạn sẽ nhận được kết xuất trông giống như sau:

 
Thuộc tính className đã được giới thiệu để ngăn xung đột với từ khóa lớp được tìm thấy trong JavaScript và các ngôn ngữ khác có quyền truy cập vào DOM. Bạn có thể sử dụng className để gán giá trị trực tiếp cho lớp.
// Select the first div
const div = document.querySelector('div');

// Assign the warning class to the first div
div.className = 'warning';

 Chúng tôi đã gán lớp cảnh báo được xác định trong các giá trị CSS của classes.html cho div đầu tiên. Bạn sẽ nhận được kết quả sau:

Lưu ý rằng nếu bất kỳ lớp nào đã tồn tại trên phần tử, điều này sẽ ghi đè lên chúng. Bạn có thể thêm nhiều không gian phân tách các lớp bằng cách sử dụng thuộc tính className hoặc sử dụng nó mà không có các toán tử gán để lấy giá trị của lớp trên phần tử. Một cách khác để sửa đổi các lớp là thông qua thuộc tính classList, mà đi kèm với một vài phương thức hữu ích. Các phương thức này tương tự như các phương thức jQuery addClass, removeClass và toggleClass.
// Select the second div by class name
const activeDiv = document.querySelector('.active');

activeDiv.classList.add('hidden');                // Add the hidden class
activeDiv.classList.remove('hidden');             // Remove the hidden class
activeDiv.classList.toggle('hidden');             // Switch between hidden true and false
activeDiv.classList.replace('active', 'warning'); // Replace active class with warning class
Sau khi thực hiện các phương pháp trên, trang web của bạn sẽ trông như sau:

Không giống như trong ví dụ className, sử dụng classList.add () sẽ thêm một lớp mới vào danh sách các lớp hiện có. Bạn cũng có thể thêm nhiều lớp dưới dạng các chuỗi được phân tách bằng dấu phẩy. Cũng có thể sử dụng setAttribute để sửa đổi lớp của một phần tử.

Sửa đổi style

Thuộc tính style repesents các style nội tuyến trên một phần tử HTML. Thông thường, các kiểu sẽ được áp dụng cho các phần tử thông qua biểu định kiểu như chúng ta đã làm trước đó trong bài viết này, nhưng đôi khi chúng ta phải thêm hoặc chỉnh sửa trực tiếp style nội tuyến. Chúng tôi sẽ tạo một ví dụ ngắn để minh họa các kiểu chỉnh sửa bằng JavaScript. Dưới đây là một tệp HTML mới với một div có một số style nội tuyến được áp dụng để hiển thị một hình vuông.
styles.html
<!DOCTYPE html>
<html lang="en">

<body>

    <div style="height: 100px;
                width: 100px;
                border: 2px solid black;">Div</div>

</body>

</html>

 Khi được mở trong trình duyệt web, styles.html sẽ trông giống như sau:

 
Một tùy chọn để chỉnh sửa style là với setAttribute ().
// Select div
const div = document.querySelector('div');

// Apply style to div
div.setAttribute('style', 'text-align: center');
Tuy nhiên, điều này sẽ xóa tất cả các style nội tuyến hiện có khỏi phần tử. Vì đây có thể không phải là hiệu ứng dự định, nên sử dụng trực tiếp thuộc tính style
div.style.height = '100px';
div.style.width = '100px';
div.style.border = '2px solid black';
 
Thuộc tính CSS được viết bằng kebab-case, là các chữ thường được phân cách bằng dấu gạch ngang. Điều quan trọng cần lưu ý là không thể sử dụng thuộc tính CSS kebab-case trên thuộc tính style JavaScript. Thay vào đó, chúng sẽ được thay thế bằng tương đương camelCase của chúng, đó là khi từ đầu tiên là chữ thường và tất cả các từ tiếp theo được viết hoa. Nói cách khác, thay vì căn chỉnh văn bản, chúng tôi sẽ sử dụng textAlign cho thuộc tính kiểu JavaScript.
// Make div into a circle and vertically center the text
div.style.borderRadius = '50%';
div.style.display = 'flex';
div.style.justifyContent = 'center';
div.style.alignItems = 'center';
Sau khi hoàn tất các sửa đổi style ở trên, kết xuất cuối cùng của styles.html sẽ hiển thị vòng kết nối:

 Nếu nhiều thay đổi style được áp dụng cho một phần tử, thì hành động tốt nhất là áp dụng kiểu cho một lớp và thêm một lớp mới. Tuy nhiên, có một số trường hợp trong đó việc sửa đổi thuộc tính stlye inline sẽ là cần thiết hoặc đơn giản hơn.

Phần kết luận

Các phần tử HTML thường có thông tin bổ sung được gán cho chúng dưới dạng các thuộc tính. Thuộc tính có thể bao gồm các cặp tên / giá trị và một vài thuộc tính phổ biến nhất là class và style. Trong hướng dẫn này, chúng tôi đã học cách truy cập, sửa đổi và loại bỏ các thuộc tính trên một phần tử HTML trong DOM bằng cách sử dụng JavaScript thuần túy. Chúng tôi cũng đã học cách thêm, xóa, chuyển đổi và thay thế các lớp CSS trên một phần tử và cách chỉnh sửa các kiểu CSS nội tuyến. Để đọc thêm, hãy xem tài liệu về các thuộc tính trên Mạng nhà phát triển Mozilla.

Bài dịch từ nguồn https://www.digitalocean.com/community/tutorials/how-to-modify-attributes-classes-and-styles-in-the-dom

Xin cảm ơn các bạn đã theo dõi bài viết của Nguyên Vũ.