Nhận danh sách lớp cho phần tử với jQuery


656

Có cách nào trong jQuery để lặp qua hoặc gán cho một mảng tất cả các lớp được gán cho một phần tử không?

Ví dụ.

<div class="Lorem ipsum dolor_spec sit amet">Hello World!</div>

Tôi sẽ tìm kiếm một lớp "đặc biệt" như trong "dolor_spec" ở trên. Tôi biết rằng tôi có thể sử dụng hasClass () nhưng tên lớp thực tế có thể không nhất thiết phải được biết vào thời điểm đó.


Nếu bạn không biết tên lớp tại thời điểm đó, ngăn bạn sử dụng hasClass (), làm thế nào để bạn biết tên nào trong mảng đó?
doomspork

Tôi đang thiết kế một biểu mẫu nơi tôi đang thực hiện một số xác nhận sơ bộ với jQuery. Tôi đang thêm id của phần tử đầu vào vào danh sách lớp của div lỗi nếu được tạo. Tôi sau đó làm cho nó có thể nhấp vào div lỗi để tập trung vào phần tử đầu vào sai lầm. Kịch bản này sẽ được sử dụng cho nhiều hơn một hình thức. Do đó, tôi không muốn mã cứng các id trong tập lệnh.
Buggabill

1
Phải, tôi hiểu lý do tại sao bạn không muốn mã hóa cứng. Nhưng nếu bạn dành một chút thời gian để xem qua ví dụ của redsapes, bạn sẽ thấy bạn đã mã hóa 'someClass' vào khối if. Dù bằng cách nào bạn cũng có thể đạt được điều này với một biến.
doomspork

Thay vì sử dụng thuộc tính lớp, bạn có thể có một biến danh sách lỗi bên trong không gian tên chứa các tham chiếu DOM đến các phần tử có lỗi. Do đó, loại bỏ sự cần thiết phải kéo danh sách thuộc tính mỗi lần, lặp lại nó, tìm phần tử DOM và tập trung vào nó.
doomspork

Câu trả lời:


731

Bạn có thể sử dụng document.getElementById('divId').className.split(/\s+/);để giúp bạn có một loạt các tên lớp.

Sau đó, bạn có thể lặp đi lặp lại và tìm thấy một trong những bạn muốn.

var classList = document.getElementById('divId').className.split(/\s+/);
for (var i = 0; i < classList.length; i++) {
    if (classList[i] === 'someClass') {
        //do something
    }
}

jQuery không thực sự giúp bạn ở đây ...

var classList = $('#divId').attr('class').split(/\s+/);
$.each(classList, function(index, item) {
    if (item === 'someClass') {
        //do something
    }
});

4
đó chính xác là những gì tôi đã làm, nhưng tôi không chắc liệu có một bản dựng trong hàm jQuery đã cung cấp cho bạn một bộ sưu tập các lớp hay không.
Sander

36
FYI: jQuery sử dụng className.split (/ \ s + /)
kͩeͣmͮpͥ

70
Tự thêm một plugin jQuery:$.fn.classList = function() {return this[0].className.split(/\s+/);};
ripper234

1
hoặc sau đó bạn có thể: if ($.inArray("someclass",classList)>=0) { /* hasClass someclass*/ }
sambomartin

Không phải là một chuyên gia javascript ở đây. Bạn có thể cho tôi biết nếu split (/ \ s + /) tốt hơn chỉ đơn giản là thực hiện split ("") không? Nó hoạt động tương tự với tôi trong FF23 / Chrome28 / IE8.
Roberto Linares

288

Tại sao không có ai liệt kê đơn giản.

$(element).attr("class").split(/\s+/);

EDIT: Như @MarkAmery chỉ ra, bạn không thể chỉ .split(' ')vì tên lớp có thể được phân tách bằng bất kỳ loại khoảng trắng nào.


6
Đó là một phần của câu trả lời được chấp nhận ... Tôi cần tất cả các lớp được áp dụng cho một phần tử.
Buggabill

54
Bởi vì nó sai! Các lớp có thể được phân tách bằng bất kỳ loại khoảng trắng nào (ví dụ: bạn có thể bọc một thuộc tính lớp dài trong HTML của mình lên nhiều dòng), nhưng câu trả lời này không giải thích được điều đó. Hãy thử dán $('<div class="foo bar baz">').attr("class").split(' ')vào bảng điều khiển trình duyệt của bạn (có một ký tự tab trong đó); bạn sẽ nhận được ["foo", "bar baz"]thay vì danh sách lớp chính xác ["foo", "bar", "baz"].
Đánh dấu Amery

2
@MarkAmery đã đúng. Nếu bạn có một class="foo <lots of spaces here> bar", bạn sẽ kết thúc với một mảng với các phần tử chuỗi rỗng.
Jacob van Lingen

4
Tôi nghĩ rằng trong 99% trường hợp giải pháp này là hiệu quả, tức là cung cấp cho bạn quyền kiểm soát HTML. Tôi không thể nghĩ ra bất kỳ lý do nào chúng tôi sẽ cần để hỗ trợ khả năng của các tab hoặc nhiều khoảng trắng giữa các tên lớp ngay cả khi các tiêu chuẩn HTML cho phép điều này.
Gordon Rouse

5
@GordonRouse một không gian bổ sung leo vào danh sách các lớp là khá phổ biến, đặc biệt nếu một loại logic nào đó viết ra danh sách các lớp.
Eric

142

Trên các trình duyệt hỗ trợ, bạn có thể sử dụng thuộc tính của các thành phần DOM classList.

$(element)[0].classList

Nó là một đối tượng giống như mảng liệt kê tất cả các lớp mà phần tử có.

Nếu bạn cần hỗ trợ các phiên bản trình duyệt cũ không hỗ trợ thuộc classListtính, trang MDN được liên kết cũng bao gồm một shim cho nó - mặc dù ngay cả shim sẽ không hoạt động trên các phiên bản Internet Explorer bên dưới IE 8.


Câu trả lời sạch sẽ và không phát minh lại bánh xe.
Marco Sulla

@Marco Sulla: điều này thực sự có một thiếu sót ngoài việc hỗ trợ trên phần mềm lỗi thời. .classListkhông phải là một mảng thực sự và các phương thức như .indexOf(⋯)vậy không hoạt động trên nó. Nó chỉ là một đối tượng giống như mảng, trong khi .className.split(/\s+/).indexOf(⋯)(từ câu trả lời được chấp nhận) hoạt động.
Incni Mrsi

Bạn có thể dễ dàng chuyển đổi bất kỳ lần lặp nào sang Arraysử dụng [...iterable]hoặcArray.from(iterable)
Marco Sulla

142

Đây là một plugin jQuery sẽ trả về một mảng của tất cả các lớp mà (các) phần tử phù hợp có

;!(function ($) {
    $.fn.classes = function (callback) {
        var classes = [];
        $.each(this, function (i, v) {
            var splitClassName = v.className.split(/\s+/);
            for (var j = 0; j < splitClassName.length; j++) {
                var className = splitClassName[j];
                if (-1 === classes.indexOf(className)) {
                    classes.push(className);
                }
            }
        });
        if ('function' === typeof callback) {
            for (var i in classes) {
                callback(classes[i]);
            }
        }
        return classes;
    };
})(jQuery);

Sử dụng nó như

$('div').classes();

Trong trường hợp của bạn trở về

["Lorem", "ipsum", "dolor_spec", "sit", "amet"]

Bạn cũng có thể truyền một hàm cho phương thức được gọi trên mỗi lớp

$('div').classes(
    function(c) {
        // do something with each class
    }
);

Đây là một jsFiddle tôi thiết lập để trình diễn và kiểm tra http://jsfiddle.net/GD8Qn/8/

Javascript tối thiểu

;!function(e){e.fn.classes=function(t){var n=[];e.each(this,function(e,t){var r=t.className.split(/\s+/);for(var i in r){var s=r[i];if(-1===n.indexOf(s)){n.push(s)}}});if("function"===typeof t){for(var r in n){t(n[r])}}return n}}(jQuery);

Hoàn toàn phù hợp với FullCalWiki khi sao chép các lớp vào thuộc tính className của một Sự kiện.
Dan Power

78

Bạn nên thử cái này:

$("selector").prop("classList")

Nó trả về một mảng của tất cả các lớp hiện tại của phần tử.


Đây là câu trả lời gọn gàng hơn nhiều, có lý do nào để không sử dụng phương pháp này không?
RozzA

5
À tôi không biết. Nhưng đây là cách thích hợp để lấy thuộc tính từ phần tử DOM. Và "classList" là thuộc tính như vậy cung cấp cho bạn một mảng các lớp css được áp dụng cho phần tử.
P.Petkov

@RozzA Có lẽ nó không có sẵn sau đó? Nhưng tôi muốn nói rằng đây là phương pháp phù hợp nhất hiện nay, trừ khi bạn không sử dụng jQuery, trong đó .classListgiải pháp đơn giản - bạn chỉ cần chú ý đến sự không nhất quán và / hoặc thiếu hỗ trợ trình duyệt ..
Dennis98

@ Dennis98 cuộc gọi tốt, đôi khi tôi quên rằng các tính năng mới đã xuất hiện nhanh chóng như thế nào gần đây. Tôi cũng đã thực hiện js đơn giản, .classListnó hoạt động khá tốt trong các trình duyệt hiện đại
RozzA

1
Lưu ý rằng thuộc classListtính không hoạt động trên IE 10/11 cho các phần tử SVG (mặc dù nó hoạt động cho các phần tử HTML). Xem developer.mozilla.org/en-US/docs/Web/API/Euity/
classList

17
var classList = $(element).attr('class').split(/\s+/);
$(classList).each(function(index){

     //do something

});

7

Cập nhật:

Như @Ryan Leonard đã chỉ ra một cách chính xác, câu trả lời của tôi không thực sự khắc phục điểm tôi tự làm ... Bạn cần phải cắt và loại bỏ khoảng trắng kép bằng (ví dụ) string.replace (/ + / g, "") .. Hoặc bạn có thể tách el. ClassName và sau đó xóa các giá trị trống bằng (ví dụ) Array.filter (Boolean).

const classes = element.className.split(' ').filter(Boolean);

hoặc hiện đại hơn

const classes = element.classList;

Cũ:

Với tất cả các câu trả lời đã cho, bạn không bao giờ nên quên người dùng .trim () (hoặc $ .trim ())

Vì các lớp được thêm và xóa, nên có thể có nhiều khoảng trắng giữa chuỗi lớp .. ví dụ: 'class1 class2 class3' ..

Điều này sẽ biến thành ['class1', 'class2', '', '', '', 'class3'] ..

Khi bạn sử dụng trim, tất cả nhiều khoảng trắng sẽ bị xóa ..


2
Điều này là không chính xác (và không phải là một câu trả lời). Cả String.trim () và $ .trim () xóa tất cả khoảng trắng hàng đầu và dấu kiểm và để phần còn lại của chuỗi. jsconsole.com /?% 22% 20% 20a% 20% 20b% 20% 20% 22.trim ()
Ryan Leonard

Bạn thậm chí đã có một cái nhìn vào các câu trả lời? Tất cả các giải pháp JS gốc không kiểm tra các khoảng trắng hàng đầu và dấu kiểm, do đó đưa ra một danh sách lớp bị lỗi, vì sẽ có các lớp trống trong mảng .. jQuery thực hiện tương tự bên trong khi đọc các lớp
DutchKevv

2
Tôi đã thấy các câu trả lời khác và đồng ý rằng khoảng trắng nên được loại bỏ giữa các tên lớp. Tôi đã chỉ ra rằng a) đây phải là một nhận xét về các giải pháp khác, vì nó không phải là một câu trả lời hoàn chỉnh b) .trim () không xóa nhiều khoảng trắng để đạt được những gì bạn cần.
Ryan Leonard

1
Bạn hoàn toàn chính xác ... Xin lỗi vì nhận xét nhanh của tôi .. Nó không xóa khoảng trắng ở giữa ... s.trim (). Thay thế (/ + / g, "") hoặc một cái gì đó sẽ là cần thiết để loại bỏ tất cả nhiều khoảng trắng ở giữa các lớp .. Bên cạnh đó, el. classList gần như được hỗ trợ rộng rãi, sửa tất cả những gì tôi cho là ..
DutchKevv

1
không có vấn đề gì cả. Hạnh phúc nâng cao, .classListlà một cách tiếp cận sạch sẽ hơn nhiều!
Ryan Leonard

7
$('div').attr('class').split(' ').each(function(cls){ console.log(cls);})

2
Đây là một sự lạm dụng khủng khiếp .map; sử dụng .eachnếu bạn không cần .mapgiá trị trả về. Chia tách trên các khoảng trắng thay vì bất kỳ khoảng trắng nào cũng bị hỏng - hãy xem nhận xét của tôi về stackoverflow.com/a/10159062/1709587 . Ngay cả khi không có điểm nào trong số này là đúng, thì điều này không thêm gì mới vào trang. -1!
Đánh dấu Amery

3

Điều này có thể giúp bạn quá. Tôi đã sử dụng chức năng này để có được các lớp của phần tử con ..

function getClickClicked(){
    var clickedElement=null;
    var classes = null;<--- this is array
    ELEMENT.on("click",function(e){//<-- where element can div,p span, or any id also a class
        clickedElement = $(e.target);
        classes = clickedElement.attr("class").split(" ");
        for(var i = 0; i<classes.length;i++){
            console.log(classes[i]);
        }
        e.preventDefault();
    });
}

Trong trường hợp của bạn, bạn muốn lớp doler_ipsum bạn có thể làm như thế này ngay bây giờ calsses[2];.


2

Cảm ơn vì điều này - Tôi đã gặp một vấn đề tương tự, vì tôi đang cố gắng lập trình các đối tượng sẽ lập trình các tên lớp phân cấp, mặc dù các tên đó có thể không nhất thiết phải được biết đến theo kịch bản của tôi.

Trong tập lệnh của tôi, tôi muốn một <a>thẻ bật / tắt văn bản trợ giúp bằng cách đưa <a>thẻ [some_class]cộng với lớp togglevà sau đó cung cấp cho nó văn bản trợ giúp cho lớp [some_class]_toggle. Mã này đang tìm thành công các yếu tố liên quan bằng jQuery:

$("a.toggle").toggle(function(){toggleHelp($(this), false);}, function(){toggleHelp($(this), true);});

function toggleHelp(obj, mode){
    var classList = obj.attr('class').split(/\s+/);
    $.each( classList, function(index, item){
    if (item.indexOf("_toggle") > 0) {
       var targetClass = "." + item.replace("_toggle", "");
       if(mode===false){$(targetClass).removeClass("off");}
       else{$(targetClass).addClass("off");}
    }
    });
} 

Cảm ơn Alan, tôi đang làm một cái gì đó tương tự, tôi ngạc nhiên rằng không có cách nào đơn giản hơn để làm điều này.
Eric Kigathi

- 1 - tl; dr, tắt một tiếp tuyến không liên quan trực tiếp đến câu hỏi.
Đánh dấu Amery

2

Thử cái này. Điều này sẽ giúp bạn có tên của tất cả các lớp từ tất cả các yếu tố của tài liệu.

$(document).ready(function() {
var currentHtml="";
$('*').each(function() {
    if ($(this).hasClass('') === false) {
        var class_name = $(this).attr('class');
        if (class_name.match(/\s/g)){
            var newClasses= class_name.split(' ');
            for (var i = 0; i <= newClasses.length - 1; i++) {
                if (currentHtml.indexOf(newClasses[i]) <0) {
                    currentHtml += "."+newClasses[i]+"<br>{<br><br>}<br>"
                }
            }
        }
        else
        {
            if (currentHtml.indexOf(class_name) <0) {
                currentHtml += "."+class_name+"<br>{<br><br>}<br>"
            }
        }
    }
    else
    {
        console.log("none");
    }
});
$("#Test").html(currentHtml);

});

Dưới đây là ví dụ hoạt động: https://jsfiddle.net/raju_sumit/2xu1ujoy/3/


1

Tôi đã có một vấn đề tương tự, đối với một yếu tố của hình ảnh loại. Tôi cần kiểm tra xem phần tử đó có thuộc một lớp nhất định không. Đầu tiên tôi đã thử với:

$('<img>').hasClass("nameOfMyClass"); 

nhưng tôi nhận được một "chức năng này không có sẵn cho phần tử này".

Sau đó, tôi đã kiểm tra phần tử của mình trên DOM explorer và tôi thấy một thuộc tính rất hay mà tôi có thể sử dụng: className. Nó chứa tên của tất cả các lớp của phần tử của tôi được phân tách bằng khoảng trắng.

$('img').className // it contains "class1 class2 class3"

Một khi bạn nhận được điều này, chỉ cần tách chuỗi như bình thường.

Trong trường hợp của tôi, điều này đã làm việc:

var listOfClassesOfMyElement= $('img').className.split(" ");

Tôi giả sử điều này sẽ hoạt động với các loại yếu tố khác (ngoài img).

Hy vọng nó giúp.


0

javascript cung cấp một thuộc tính classList cho một phần tử nút trong dom. Đơn giản chỉ cần sử dụng

  element.classList

sẽ trả về một đối tượng của hình thức

  DOMTokenList {0: "class1", 1: "class2", 2: "class3", length: 3, item: function, contains: function, add: function, remove: function…}

Đối tượng có các chức năng như chứa, thêm, xóa mà bạn có thể sử dụng


Bản sao kém hơn của stackoverflow.com/a/5457148/1709587 đã được đăng 3 năm trước bạn; -1.
Đánh dấu Amery

-3

Hơi muộn một chút, nhưng sử dụng hàm extend () cho phép bạn gọi "hasClass ()" trên bất kỳ phần tử nào, ví dụ:
var hasClass = $('#divId').hasClass('someClass');

(function($) {
$.extend({
    hasClass: new function(className) {
        var classAttr = $J(this).attr('class');
        if (classAttr != null && classAttr != undefined) {
            var classList = classAttr.split(/\s+/);
            for(var ix = 0, len = classList.length;ix < len;ix++) {
                if (className === classList[ix]) {
                    return true;
                }
            }
        }
        return false;
    }
}); })(jQuery);

10
Đó không phải là câu hỏi.
Tomas

5
Ngoài ra, jQuery đã tích hợp sẵn chức năng này kể từ phiên bản 1.2.
Andrew

-3

Câu hỏi là Jquery được thiết kế để làm gì.

$('.dolor_spec').each(function(){ //do stuff

Và tại sao không có ai đưa ra .find () như một câu trả lời?

$('div').find('.dolor_spec').each(function(){
  ..
});

Ngoài ra còn có classList cho các trình duyệt không phải IE:

if element.classList.contains("dolor_spec") {  //do stuff

3
- 1; trong số các vấn đề khác, hai đoạn mã đầu tiên của bạn không liên quan đến câu hỏi được hỏi và đoạn mã cuối cùng của bạn là một lỗi cú pháp.
Đánh dấu Amery

-4

Ở đây bạn đi, chỉ cần điều chỉnh câu trả lời của readapes để trả về một mảng của tất cả các lớp:

function classList(elem){
   var classList = elem.attr('class').split(/\s+/);
    var classes = new Array(classList.length);
    $.each( classList, function(index, item){
        classes[index] = item;
    });

    return classes;
}

Truyền phần tử jQuery cho hàm, để một cuộc gọi mẫu sẽ là:

var myClasses = classList($('#myElement'));

3
Tại sao lặp qua mảng classList, thêm tất cả các phần tử vào mảng lớp và trả về mảng lớp? Chỉ cần trả về classList nên thực hiện cùng một mẹo, phải không?
Martijn

Không. Vì chúng ta đang đề cập đến một tình huống có nhiều lớp cho cùng một phần tử. Nếu nó quá dễ, chúng ta sẽ không ở đây trong chủ đề này :)
Gregra

8
Chủ đề này là về việc trả về một danh sách các lớp và chỉ cần trả về $(elem).attr('class').split(/\s+/)làm điều đó. Có thể tôi đang nhầm, nhưng tôi không thấy bất kỳ lý do nào để lặp qua bộ sưu tập, sao chép nội dung vào bộ sưu tập mới và trả lại bộ sưu tập mới đó.
Martijn

-4

Tôi biết đây là một câu hỏi cũ nhưng vẫn còn.

<div id="specId" class="Lorem ipsum dolor_spec sit amet">Hello World!</div>

var className=".dolor_spec" //dynamic

Nếu bạn muốn thao tác phần tử

$("#specId"+className).addClass('whatever');

Nếu bạn muốn kiểm tra xem phần tử có lớp không

 $("#specId"+className).length>0

nếu nhiều lớp

//if you want to select ONE of the classes
var classNames = ['.dolor_spec','.test','.test2']
$("#specId"+classNames).addClass('whatever');
$("#specId"+classNames).length>0
//if you want to select all of the classes
var result = {className: ""};
classNames.forEach(function(el){this.className+=el;},result);
var searchedElement= $("#specId"+result.className);
searchedElement.addClass('whatever');
searchedElement.length>0

1
Không có đoạn trích nào trong số các câu hỏi được hỏi cả; -1.
Đánh dấu Amery
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.