Có cách nào để thêm / xóa một vài lớp trong một lệnh đơn với classList không?


164

Cho đến nay tôi phải làm điều này:

elem.classList.add("first");
elem.classList.add("second");
elem.classList.add("third");

Trong khi điều này là có thể thực hiện được trong jQuery, như thế này

$(elem).addClass("first second third");

Tôi muốn biết nếu có bất kỳ cách riêng để thêm hoặc xóa.

Câu trả lời:


313
elem.classList.add("first");
elem.classList.add("second");
elem.classList.add("third");

bằng nhau

elem.classList.add("first","second","third");

15
Và nếu bạn muốn áp dụng Mảng gồm một số tên lớp, bạn phải gọi: DOMTokenList.prototype.add.apply (elem. ClassList, ['first', 'second', 'third']);
Emanuel Kluge

8
Firefox cũng không hỗ trợ nó tại thời điểm viết bài. Câu trả lời của tôi cung cấp một polyfill.
Andy E

Tôi đang chuyển sang câu trả lời này là câu trả lời đúng, vì đây là API gốc, ngay cả khi hỗ trợ không tốt.
Lều Enrique Moreno

1
Bạn đã xem xét el.groupName + = "các lớp học của tôi ở đây chưa"
Michael Tontchev

1
có cách nào để xóa nhiều lớp không
MeVimalkumar

71

Toán tử trải rộng mới giúp dễ dàng áp dụng nhiều lớp CSS dưới dạng mảng:

const list = ['first', 'second', 'third'];
element.classList.add(...list);

1
Câu trả lời được chấp nhận hoạt động với một danh sách trực tiếp các giá trị, nhưng câu trả lời này hoạt động với mảng ... cả hai câu trả lời có vẻ xuất sắc!
Lều Enrique Moreno

Tôi có thể sử dụng DOMTokenListthay vì một mảng? Tôi biết rằng DOMTokenList là một đối tượng giống như mảng. Vì vậy, có thể sử dụng nó theo classList.add()phương thức hoặc DOMTokenList phải được chuyển đổi trong một mảng thực?
xela84

19

Các classListtài sản đảm bảo rằng các lớp trùng lặp không cần thiết thêm vào nguyên tố này. Để giữ cho chức năng này, nếu bạn không thích các phiên bản longhand hoặc phiên bản jQuery, tôi muốn đề nghị bổ sung thêm một addManychức năng và removeManyđến DOMTokenList(các loại classList):

DOMTokenList.prototype.addMany = function(classes) {
    var array = classes.split(' ');
    for (var i = 0, length = array.length; i < length; i++) {
      this.add(array[i]);
    }
}

DOMTokenList.prototype.removeMany = function(classes) {
    var array = classes.split(' ');
    for (var i = 0, length = array.length; i < length; i++) {
      this.remove(array[i]);
    }
}

Chúng có thể được sử dụng như vậy:

elem.classList.addMany("first second third");
elem.classList.removeMany("first third");

Cập nhật

Theo nhận xét của bạn, nếu bạn chỉ muốn viết một phương thức tùy chỉnh cho những điều này trong trường hợp chúng không được xác định, hãy thử như sau:

DOMTokenList.prototype.addMany = DOMTokenList.prototype.addMany || function(classes) {...}
DOMTokenList.prototype.removeMany = DOMTokenList.prototype.removeMany || function(classes) {...}

Vẫn là một câu trả lời tốt. Và tôi không thể chỉnh sửa nó cho bạn vì nó chỉ có 2 ký tự.
Pete

18

add()phương thức từ classListchỉ cho phép truyền các đối số riêng biệt và không phải là một mảng duy nhất, nên bạn cần add()sử dụng invoque . Đối với đối số đầu tiên, bạn sẽ cần chuyển classListtham chiếu từ cùng một nút DOM và làm đối số thứ hai mảng các lớp mà bạn muốn thêm:

element.classList.add.apply(
  element.classList,
  ['class-0', 'class-1', 'class-2']
);

Đây là phiên bản giải pháp ES5 với Toán tử trải rộng (xem câu trả lời @morkro ). Kiểm tra nó dễ dàng tại Babel Thay thế .
Nickensoul

7

Để thêm lớp cho một phần tử

document.querySelector(elem).className+=' first second third';

CẬP NHẬT:

Xóa một lớp

document.querySelector(elem).className=document.querySelector(elem).className.split(class_to_be_removed).join(" ");

Điều này rất thú vị để biết, nhưng tất cả những gì nó làm là chỉnh sửa chuỗi của lớp. Nó sẽ không hoạt động nếu tôi muốn loại bỏ một số lớp. Xin lỗi, tôi quên thêm nó vào OP.
Lều Enrique Moreno

4
Đừng KHÔNG sử dụng className. Đó là khủng khiếp cho hiệu suất (thậm chí lấy giá trị của nó gây ra một dòng chảy lại).
jacob

7

Các phiên bản mới hơn của thông số DOMTokenList cho phép nhiều đối số add()remove(), cũng như đối số thứ hai toggle()để buộc trạng thái.

Tại thời điểm viết bài, Chrome hỗ trợ nhiều đối số add()remove(), nhưng không có trình duyệt nào khác làm được. IE 10 trở xuống, Firefox 23 trở xuống, Chrome 23 trở xuống và các trình duyệt khác không hỗ trợ đối số thứ hai toggle().

Tôi đã viết các polyfill nhỏ sau đây để tiết lộ cho đến khi hỗ trợ mở rộng:

(function () {
    /*global DOMTokenList */
    var dummy  = document.createElement('div'),
        dtp    = DOMTokenList.prototype,
        toggle = dtp.toggle,
        add    = dtp.add,
        rem    = dtp.remove;

    dummy.classList.add('class1', 'class2');

    // Older versions of the HTMLElement.classList spec didn't allow multiple
    // arguments, easy to test for
    if (!dummy.classList.contains('class2')) {
        dtp.add    = function () {
            Array.prototype.forEach.call(arguments, add.bind(this));
        };
        dtp.remove = function () {
            Array.prototype.forEach.call(arguments, rem.bind(this));
        };
    }

    // Older versions of the spec didn't have a forcedState argument for
    // `toggle` either, test by checking the return value after forcing
    if (!dummy.classList.toggle('class1', true)) {
        dtp.toggle = function (cls, forcedState) {
            if (forcedState === undefined)
                return toggle.call(this, cls);

            (forcedState ? add : rem).call(this, cls);
            return !!forcedState;
        };
    }
})();

Một trình duyệt hiện đại với tuân thủ ES5 và DOMTokenList được mong đợi, nhưng tôi đang sử dụng polyfill này trong một số môi trường được nhắm mục tiêu cụ thể, vì vậy nó hoạt động rất tốt cho tôi, nhưng nó có thể cần điều chỉnh cho các tập lệnh sẽ chạy trong môi trường trình duyệt cũ như IE 8 trở xuống .


1
Dường như không ai đề cập đến việc IE10 không cho phép thêm nhiều lớp. Điều này làm việc tốt cho tôi rất cảm ơn! Tôi sẽ thận trọng mặc dù trong IE9 tôi gặp một lỗi mà DomTokenList không được xác định. Bạn có thể muốn tính đến điều đó quá. Hoặc chỉ chạy cái này nếu (typeof DomTokenList! == 'không xác định')
Ryan Ore

@Ryan: cảm ơn, tôi nghĩ DOMTokenList đã được hỗ trợ trong IE 9 nhưng tôi đoán nó đã bị bỏ qua. Tôi sẽ thử và điều tra một cách giải quyết tại một số điểm.
Andy E

Có vẻ như trên một DOMTokenList không thành công, bạn phải sử dụng className với các kiểm tra regEx ranh giới từ
Greg

5

Đây là một cách giải quyết cho người dùng IE 10 và 11 có vẻ khá dễ dàng.

var elem = document.getElementById('elem');

['first','second','third'].map(item => elem.classList.add(item));
<div id="elem">Hello World!</div>

Hoặc là

var elem = document.getElementById('elem'),
    classes = ['first','second','third'];

classes.map(function(item) {
    return elem.classList.add(item);
});
<div id="elem">Hello World!</div>


5
Ý kiến ​​hay. Tôi sẽ sử dụng .forEach () thay vì .map () - nó sạch hơn / hiệu quả hơn cho các tình huống như thế này khi bạn không sử dụng mảng trả về.
tenni

Vâng đó là sự thật.
colecmc

5

Bạn có thể làm như dưới đây

Thêm vào

elem.classList.add("first", "second", "third");

Tẩy

elem.classList.remove("first", "second", "third");

Tài liệu tham khảo

TLDR;

Trong trường hợp thẳng phía trên loại bỏ nên làm việc. Nhưng trong trường hợp loại bỏ, bạn nên đảm bảo lớp tồn tại trước khi bạn loại bỏ chúng

const classes = ["first","second","third"];
classes.forEach(c => {
  if (elem.classList.contains(c)) {
     element.classList.remove(c);
  }
})

2

Definiton tiêu chuẩn chỉ cho phép thêm hoặc xóa một lớp duy nhất. Một vài hàm bao bọc nhỏ có thể làm những gì bạn yêu cầu:

function addClasses (el, classes) {
  classes = Array.prototype.slice.call (arguments, 1);
  console.log (classes);
  for (var i = classes.length; i--;) {
    classes[i] = classes[i].trim ().split (/\s*,\s*|\s+/);
    for (var j = classes[i].length; j--;)
      el.classList.add (classes[i][j]);
  }
}

function removeClasses (el, classes) {
  classes = Array.prototype.slice.call (arguments, 1);
  for (var i = classes.length; i--;) {
    classes[i] = classes[i].trim ().split (/\s*,\s*|\s+/);
    for (var j = classes[i].length; j--;)
      el.classList.remove (classes[i][j]);
  }
}

Các hàm bao này cho phép bạn chỉ định danh sách các lớp dưới dạng các đối số riêng biệt, dưới dạng các chuỗi có các mục được phân tách bằng dấu cách hoặc dấu phẩy hoặc kết hợp. Để biết ví dụ, hãy xem http://jsfiddle.net/jstoolsmith/eCqy7


2

Một giải pháp rất đơn giản, không cầu kỳ, nhưng hiệu quả mà tôi phải tin là trình duyệt rất chéo:

Tạo chức năng này

function removeAddClasses(classList,removeCollection,addCollection){
    for (var i=0;i<removeCollection.length;i++){ 
        classList.remove(removeCollection[i]); 
    }
    for (var i=0;i<addCollection.length;i++){ 
        classList.add(addCollection[i]); 
    }
}

Gọi nó như thế này: removeAddClass (node. ClassList, ArrayToRemove, ArrayToAdd);

... Trong đó mảngToRemove là một mảng các tên lớp cần loại bỏ: ['myClass1', 'myClass2'] vân vân

... và mảngToAdd là một mảng các tên lớp cần thêm: ['myClass3', 'myClass4'] vân vân


1

Giả sử rằng bạn có một mảng các lớp được thêm vào, bạn có thể sử dụng cú pháp lây lan ES6:

let classes = ['first', 'second', 'third']; elem.classList.add(...classes);


0

Tôi thích câu trả lời của @ rich.kelly, nhưng tôi muốn sử dụng danh pháp tương tự như classList.add()(chuỗi được phân tách bằng dấu phẩy), do đó, độ lệch nhẹ.

DOMTokenList.prototype.addMany = DOMTokenList.prototype.addMany || function() {
  for (var i = 0; i < arguments.length; i++) {
    this.add(arguments[i]);
  }
}
DOMTokenList.prototype.removeMany = DOMTokenList.prototype.removeMany || function() {
  for (var i = 0; i < arguments.length; i++) {
    this.remove(arguments[i]);
  }
}

Vì vậy, bạn có thể sử dụng:

document.body.classList.addMany('class-one','class-two','class-three');

Tôi cần kiểm tra tất cả các trình duyệt, nhưng điều này đã làm việc cho Chrome.
Chúng ta có nên kiểm tra một cái gì đó cụ thể hơn sự tồn tại của DOMTokenList.prototype.addMany? Điều gì chính xác gây ra classList.add()lỗi trong IE11?


0

Một polyfill khác element.classListở đây . Tôi tìm thấy nó qua MDN .

Tôi bao gồm tập lệnh đó và sử dụng element.classList.add("first","second","third")như dự định của nó.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.