Câu hỏi Thay đổi lớp của phần tử bằng JavaScript


Làm thế nào tôi có thể thay đổi một lớp của một phần tử HTML để đáp ứng với một onClick sự kiện bằng JavaScript?


2290
2017-10-12 20:06


gốc


"Thuộc tính lớp được sử dụng chủ yếu để trỏ đến một lớp trong một biểu định kiểu. Tuy nhiên, nó cũng có thể được sử dụng bởi một JavaScript (thông qua HTML DOM) để thay đổi các phần tử HTML với một lớp được chỉ định." - -w3schools.com/tags/att_standard_class.asp - Triynko
element.setAttribute(name, value);  Thay thế name với class. Thay thế value với bất kỳ tên nào bạn đã cho lớp, kèm theo trong dấu ngoặc kép. Điều này tránh phải xóa lớp hiện tại và thêm lớp khác. Điều này Ví dụ jsFiddle hiển thị mã làm việc đầy đủ. - Sandy Good
Để thay đổi lớp học của phần tử HTML bằng onClick, hãy sử dụng mã này: <input type='button' onclick='addNewClass(this)' value='Create' />   và trong phần javascript: function addNewClass(elem){ elem.className="newClass"; } Trực tuyến - Iman Bahrampour


Các câu trả lời:


Kỹ thuật HTML5 hiện đại để thay đổi lớp học

Các trình duyệt hiện đại đã được thêm classList cung cấp các phương thức để dễ dàng thao tác các lớp mà không cần thư viện:

document.getElementById("MyElement").classList.add('MyClass');

document.getElementById("MyElement").classList.remove('MyClass');

if ( document.getElementById("MyElement").classList.contains('MyClass') )

document.getElementById("MyElement").classList.toggle('MyClass');

Thật không may, chúng không hoạt động trong Internet Explorer trước phiên bản 10, mặc dù có một shim để thêm hỗ trợ cho IE8 và IE9, có sẵn từ trang này. Đó là, mặc dù, nhận được nhiều hơn và nhiều hơn nữa được hỗ trợ.

Giải pháp trình duyệt chéo đơn giản

Cách JavaScript chuẩn để chọn một phần tử đang sử dụng document.getElementById("Id"), đó là những gì các ví dụ sau đây sử dụng - bạn tất nhiên có thể có được các yếu tố theo những cách khác, và trong tình huống phù hợp có thể chỉ đơn giản là sử dụng this thay vào đó - tuy nhiên, đi vào chi tiết về điều này nằm ngoài phạm vi của câu trả lời.

Để thay đổi tất cả các lớp cho một phần tử:

Để thay thế tất cả các lớp hiện có bằng một hoặc nhiều lớp mới, hãy đặt thuộc tính className:

document.getElementById("MyElement").className = "MyClass";

(Bạn có thể sử dụng một danh sách phân cách bằng dấu cách để áp dụng nhiều lớp.)

Để thêm một lớp bổ sung vào một phần tử:

Để thêm một lớp vào một phần tử, mà không xóa / ảnh hưởng đến các giá trị hiện có, hãy thêm một khoảng trắng và một tên lớp mới, như sau:

document.getElementById("MyElement").className += " MyClass";

Để xóa lớp khỏi phần tử:

Để loại bỏ một lớp đơn lẻ thành một phần tử, mà không ảnh hưởng đến các lớp tiềm năng khác, cần thay thế regex đơn giản:

document.getElementById("MyElement").className =
   document.getElementById("MyElement").className.replace
      ( /(?:^|\s)MyClass(?!\S)/g , '' )
/* Code wrapped for readability - above is all one statement */

Giải thích về regex này như sau:

(?:^|\s) # Match the start of the string, or any single whitespace character

MyClass  # The literal text for the classname to remove

(?!\S)   # Negative lookahead to verify the above is the whole classname
         # Ensures there is no non-space character following
         # (i.e. must be end of string or a space)

Các g cờ yêu cầu thay thế lặp lại theo yêu cầu, trong trường hợp tên lớp đã được thêm nhiều lần.

Để kiểm tra xem một lớp đã được áp dụng cho một phần tử chưa:

Cùng một regex được sử dụng ở trên để loại bỏ một lớp cũng có thể được sử dụng như một kiểm tra xem liệu một lớp cụ thể có tồn tại hay không:

if ( document.getElementById("MyElement").className.match(/(?:^|\s)MyClass(?!\S)/) )


Chỉ định các hành động này cho các sự kiện onclick:

Mặc dù có thể viết JavaScript trực tiếp bên trong các thuộc tính sự kiện HTML (chẳng hạn như onclick="this.className+=' MyClass'") đây không phải là hành vi được khuyến nghị. Đặc biệt là trên các ứng dụng lớn hơn, mã có thể duy trì được nhiều hơn bằng cách tách đánh dấu HTML khỏi logic tương tác JavaScript.

Bước đầu tiên để đạt được điều này là tạo một hàm và gọi hàm trong thuộc tính onclick, ví dụ:

<script type="text/javascript">
    function changeClass(){
        // Code examples from above
    }
</script>
...
<button onclick="changeClass()">My Button</button>

(Không bắt buộc phải có mã này trong các thẻ tập lệnh, điều này đơn giản là ngắn gọn chẳng hạn, và bao gồm cả JavaScript trong một tệp riêng biệt có thể thích hợp hơn.)

Bước thứ hai là chuyển sự kiện onclick ra khỏi HTML và thành JavaScript, ví dụ: sử dụng addEventListener

<script type="text/javascript">
    function changeClass(){
        // Code examples from above
    }

    window.onload = function(){
        document.getElementById("MyElement").addEventListener( 'click', changeClass);
    }
</script>
...
<button id="MyElement">My Button</button>

(Lưu ý rằng phần window.onload được yêu cầu để nội dung của hàm đó được thi hành sau HTML đã tải xong - không có điều này, MyElement có thể không tồn tại khi mã JavaScript được gọi, vì vậy dòng đó sẽ không thành công.)


Các khung và thư viện JavaScript

Đoạn mã trên là tất cả trong JavaScript chuẩn, tuy nhiên thực tế phổ biến là sử dụng khung hoặc thư viện để đơn giản hóa các tác vụ phổ biến, cũng như lợi ích từ lỗi cố định và các trường hợp cạnh mà bạn có thể không nghĩ đến khi viết mã của mình.

Trong khi một số người cho rằng quá tải để thêm một khung hình ~ 50 KB chỉ đơn giản là thay đổi một lớp, nếu bạn đang thực hiện một số lượng đáng kể công việc JavaScript, hoặc bất kỳ thứ gì có thể có hành vi xuyên qua trình duyệt khác thường, nó cũng đáng xem xét.

(Rất gần, một thư viện là một tập hợp các công cụ được thiết kế cho một nhiệm vụ cụ thể, trong khi một khung công tác thường chứa nhiều thư viện và thực hiện một tập hợp đầy đủ các nhiệm vụ.)

Các ví dụ trên đã được sao chép dưới đây bằng cách sử dụng jQuery, có lẽ là thư viện JavaScript được sử dụng phổ biến nhất (mặc dù có những thư viện khác đáng để điều tra).

(Lưu ý rằng $ đây là đối tượng jQuery.)

Thay đổi các lớp với jQuery:

$('#MyElement').addClass('MyClass');

$('#MyElement').removeClass('MyClass');

if ( $('#MyElement').hasClass('MyClass') )

Ngoài ra, jQuery cung cấp một phím tắt để thêm một lớp nếu nó không áp dụng, hoặc loại bỏ một lớp có:

$('#MyElement').toggleClass('MyClass');


Gán một hàm cho một sự kiện nhấn với jQuery:

$('#MyElement').click(changeClass);

hoặc, không cần id:

$(':button:contains(My Button)').click(changeClass);



3302
2017-10-12 20:45



Câu trả lời tuyệt vời Peter. Một câu hỏi ... tại sao nó lại tốt hơn làm gì với JQuery hơn Javascript? JQuery là tuyệt vời, nhưng nếu đây là tất cả những gì bạn cần làm - những gì biện minh bao gồm toàn bộ JQuery libray thay vì một vài dòng mã JavaScript? - mattstuehler
@mattstuehler 1) cụm từ "tốt hơn nhưng x" thường xuyên có nghĩa là "tốt hơn (bạn có thể) x". 2) Để đạt được trọng tâm của vấn đề, jQuery được thiết kế để trợ giúp trong việc truy cập / thao tác DOM, và rất thường xuyên nếu bạn cần thực hiện điều này một khi bạn phải làm tất cả mọi nơi. - Barry
Một lỗi với giải pháp này: Khi bạn nhấp vào nút nhiều lần, nó sẽ thêm Lớp "MyClass" vào phần tử nhiều lần, thay vì kiểm tra xem nó đã tồn tại chưa. Vì vậy, bạn có thể kết thúc với một thuộc tính lớp HTML tìm kiếm một cái gì đó như thế này: class="button MyClass MyClass MyClass" - Web_Designer
Nếu bạn đang cố gắng loại bỏ một lớp 'myClass' và bạn có một lớp 'prefix-myClass' thì regex bạn đã đưa ra ở trên để loại bỏ một lớp sẽ để lại cho bạn 'prefix-' trong lớp của bạnName: O - jinglesthula
Wow, ba năm và 183 upvotes và không ai phát hiện ra cho đến bây giờ. Cảm ơn jinglesthula, tôi đã sửa regex vì vậy nó sẽ không loại bỏ không chính xác các phần của tên lớp. // Tôi đoán đây là một ví dụ tốt về lý do tại sao một Framework (như jQuery) đáng được sử dụng - các lỗi như thế này bị bắt và sửa lỗi sớm hơn, và không yêu cầu thay đổi mã bình thường. - Peter Boughton


Bạn cũng có thể làm:

document.getElementById ('id'). classList.add ('class');
document.getElementById ('id'). classList.remove ('class');

Và để chuyển đổi một lớp học (loại bỏ nếu tồn tại khác thêm nó):

document.getElementById ('id'). classList.toggle ('class');

380
2017-08-05 17:44



Tôi tin rằng điều này phụ thuộc vào HTML5. - John
Bạn sẽ cần Eli Grey’s classList shim. - ELLIOTTCABLE
đáng chú ý điều này không hoạt động trong các phiên bản IE dưới 8 .. - Lloyd
Mạng nhà phát triển Mozilla nói rằng nó không hoạt động, nguyên bản, trong Internet Explorers ít hơn 10. Tôi tìm thấy tuyên bố là đúng, trong thử nghiệm của tôi. Rõ ràng, Eli Gray shim là bắt buộc đối với Internet Explorer 8-9. Thật không may, tôi không thể tìm thấy nó trên trang web của anh ấy (ngay cả khi tìm kiếm). Các shim có sẵn trên liên kết Mozilla. - doubleJ
atow "classList" có hỗ trợ một phần trong IE10 +; không hỗ trợ Opera Mini; hỗ trợ đầy đủ khác trong các trình duyệt chuẩn còn lại: caniuse.com/#search=classlist - Nick Humphrey


Trong một trong những dự án cũ của tôi không sử dụng jQuery, tôi đã xây dựng các hàm sau đây để thêm, loại bỏ và kiểm tra nếu phần tử có lớp:

function hasClass(ele, cls) {
    return ele.className.match(new RegExp('(\\s|^)' + cls + '(\\s|$)'));
}
function addClass(ele, cls) {
    if (!hasClass(ele, cls)) ele.className += " " + cls;
}
function removeClass(ele, cls) {
    if (hasClass(ele, cls)) {
        var reg = new RegExp('(\\s|^)' + cls + '(\\s|$)');
        ele.className = ele.className.replace(reg, ' ');
    }
}

Vì vậy, ví dụ, nếu tôi muốn onclick để thêm một số lớp nút tôi có thể sử dụng này:

<script type="text/javascript">
    function changeClass(btn, cls) {
        if(!hasClass(btn, cls)) {
            addClass(btn, cls);
        }
    }
</script>
...
<button onclick="changeClass(this, "someClass")">My Button</button>

Bởi bây giờ chắc chắn nó sẽ chỉ tốt hơn để sử dụng jQuery.


98
2018-05-28 07:32



Điều này thật tuyệt vời khi khách hàng của bạn không cho phép bạn sử dụng jQuery. (Vì bạn gần như đã xây dựng xong thư viện của riêng bạn.) - Mike
@Mike Nếu khách hàng không cho phép bạn sử dụng jQuery, bạn có thể không chỉ đi qua và xây dựng lại chỉ các tính năng bạn cần vào thư viện của riêng mình? - kfrncs
@ kfrncs Vì tôi thường không cần một khung công tác lớn. Đối với dự án tôi đã nghĩ đến, các chức năng duy nhất tôi cần là các hàm lớp 3 (có, thêm, xóa) và các hàm cookie (có, thêm, xóa). Mọi thứ khác là tùy chỉnh hoặc được hỗ trợ tốt. Vì vậy, tất cả mọi thứ với nhau sau đó chỉ có 150 dòng trước khi minifying, bao gồm cả ý kiến. - Mike
Dude, 4 giờ sáng của nó và cảm ơn bạn nhiều. Vanilla JS là những gì chúng tôi đang sử dụng trong dự án của tôi và đây là một cuộc sống tiết kiệm. - LessQuesar
Đây là giải pháp yêu thích của tôi cho việc này. Tôi sử dụng nó ở mọi nơi. Tôi tin rằng đó là cách thanh lịch nhất để đạt được thêm và loại bỏ các lớp học khi dự án của bạn chưa có cách khác để thực hiện nó. - WebWanderer


Bạn có thể dùng node.className như vậy:

document.getElementById('foo').className = 'bar';

Điều này sẽ hoạt động trong IE5.5 trở lên theo PPK.


64
2017-10-12 20:33



điều này sẽ ghi đè lên bất kỳ và tất cả các lớp khác trên đối tượng ... vì vậy nó không phải là đơn giản. - Eric Sebasta


Wow, ngạc nhiên là có quá nhiều câu trả lời quá mức ở đây ...

<div class="firstClass" onclick="this.className='secondClass'">

46
2018-01-05 19:14



có, nhưng không phô trương javascript là thực hành tốt hơn .. - Lloyd
Tôi sẽ nói javascript không phô trương là thực tế khủng khiếp để viết mã ví dụ ... - Gabe
Tôi sẽ không đồng ý, bởi vì tôi nghĩ rằng mã ví dụ nên thiết lập một ví dụ tốt. - thomasrutter
Một ví dụ tốt nên hướng dẫn và châm ngòi cho trí tưởng tượng cùng một lúc. Nó không nên thay thế suy nghĩ, nhưng truyền cảm hứng cho nó. - Anthony Rutledge
Các câu trả lời khác không quá mức cần thiết, chúng cũng giữ các lớp hiện có trên phần tử. - gcampbell


Sử dụng mã JavaScript thuần túy:

function hasClass(ele, cls) {
    return ele.className.match(new RegExp('(\\s|^)' + cls + '(\\s|$)'));
}

function addClass(ele, cls) {
    if (!this.hasClass(ele, cls)) ele.className += " " + cls;
}

function removeClass(ele, cls) {
    if (hasClass(ele, cls)) {
        var reg = new RegExp('(\\s|^)' + cls + '(\\s|$)');
        ele.className = ele.className.replace(reg, ' ');
    }
}

function replaceClass(ele, oldClass, newClass){
    if(hasClass(ele, oldClass)){
        removeClass(ele, oldClass);
        addClass(ele, newClass);
    }
    return;
}

function toggleClass(ele, cls1, cls2){
    if(hasClass(ele, cls1)){
        replaceClass(ele, cls1, cls2);
    }else if(hasClass(ele, cls2)){
        replaceClass(ele, cls2, cls1);
    }else{
        addClass(ele, cls1);
    }
}

40
2017-09-20 15:26



giống như ở đây: snipplr.com/view/3561/addclass-removeclass-hasclass - Jaider


Điều này đang làm việc cho tôi:

function setCSS(eleID) {
    var currTabElem = document.getElementById(eleID);

    currTabElem.setAttribute("class", "some_class_name");
    currTabElem.setAttribute("className", "some_class_name");
}

27
2017-12-08 09:36



Câu trả lời tuyệt vời! Chỉ còn lại để thêm: Đặt cho mỗi tên lớp CSS cho bộ chọn để chỉ định kiểu cho một nhóm phần tử lớp - Roman Polen.
Điều này làm việc cho tôi trên FF, nhưng khi tôi đã cố gắng sử dụng el.className = "newStyle"; nó không hoạt động, tại sao? - Lukasz 'Severiaan' Grela
Bạn có thể dùng el.setAttribute('class', newClass)hoặc tốt hơn el.className = newClass. Nhưng không el.setAttribute('className', newClass). - Oriol