Отримайте список класів для елемента з jQuery


657

Чи існує спосіб у jQuery провести цикл чи призначити масиву всі класи, призначені елементу?

колишній

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

Я буду шукати "спеціальний" клас, як у "dolor_spec" вище. Я знаю, що я міг би використовувати hasClass (), але фактичне ім'я класу не обов'язково може бути відоме на той час.


Якщо ви не знаєте назви класу на той час, що заважає вам використовувати hasClass (), як ви маєте намір знати, який з масиву це?
doomspork

Я розробляю форму, де роблю попередню перевірку за допомогою jQuery. Я додаю ідентифікатор вхідного елемента до списку класів дива помилок, якщо такий генерується. Тоді я даю можливість натиснути на div помилку, щоб зосередити елемент введення помилки. Цей сценарій буде використовуватися для більш ніж однієї форми. Тому я не хочу жорстко кодувати ідентифікатори в сценарії.
Buggabill

1
Правильно, я розумію, чому ви не хочете робити жорсткий код. Але якщо ви знайдете хвилину, щоб переглянути приклад червоного квадрату, ви побачите, що у вас є жорсткий код 'someClass' у блок if. У будь-якому випадку ви могли б досягти цього за допомогою змінної.
doomspork

Замість того, щоб використовувати атрибут класу, ви можете мати змінну списку помилок у вашому просторі імен, яка містила посилання DOM на елементи з помилками. Таким чином, виключається необхідність щоразу витягувати список атрибутів, ітератувати його, знаходити елемент DOM та фокусувати його.
doomspork

Відповіді:


732

Ви можете використовувати document.getElementById('divId').className.split(/\s+/);для отримання масиву назв класів.

Тоді ви можете повторити і знайти потрібний.

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

jQuery насправді вам тут не допомагає ...

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

4
це саме те, що я зробив би, але я не був впевнений, чи існує збірка в jQuery функції, яка дала вам колекцію класів.
Сандер

36
FYI: jQuery використовує className.split (/ \ s + /)
kͩeͣmͮpͥ ͩ

70
Додайте плагін jQuery самостійно:$.fn.classList = function() {return this[0].className.split(/\s+/);};
ripper234

1
або тоді ви могли: if ($.inArray("someclass",classList)>=0) { /* hasClass someclass*/ }
sambomartin

Тут не експерт по JavaScript. Чи можете ви сказати мені, що спліт (/ \ s + /) краще, ніж просто робити спліт ("")? Це працює так само і для мене в FF23 / Chrome28 / IE8.
Роберто Лінарес

288

Чому його ніхто просто не перелічив.

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

EDIT: Як вказує @MarkAmery, ви не можете просто .split(' ')тому, що назви класів можна розділити будь-яким пробілом.


6
Це частина прийнятої відповіді ... Мені потрібні були всі класи, які були застосовані до елемента.
Buggabill

54
Бо це неправильно! Класи можна розділити будь-яким видом пробілів (наприклад, ви можете зв'язати довгий атрибут класу у своєму HTML на кілька рядків), але ця відповідь не враховує цього. Спробуйте вставити його $('<div class="foo bar baz">').attr("class").split(' ')в консоль браузера (там є символ вкладки); ви отримаєте ["foo", "bar baz"]замість правильного списку класів ["foo", "bar", "baz"].
Марк Амері

2
@MarkAmery має рацію. Якби у вас був a class="foo <lots of spaces here> bar", ви б закінчилися масивом з порожніми рядковими елементами.
Якоб ван Лінген

4
Я думаю, що в 99% випадків це рішення є ефективним, тобто за умови, що ви керуєте HTML. Я не можу придумати жодної причини, що нам знадобиться підтримувати можливість вкладки або кількох пробілів між іменами класів, навіть якщо стандарти стандарту HTML дозволяють це.
Гордон Роуз

5
@GordonRouse додатковий простір, що повзе до списку класів, є досить поширеним явищем, особливо якщо певна логіка виписує список класів.
Ерік

142

Підтримуючи веб-переглядачі, ви можете використовувати classListвластивість елементів DOM .

$(element)[0].classList

Це об’єкт, схожий на масив, у якому перераховані всі класи, які має елемент.

Якщо вам потрібно підтримувати старі версії веб-переглядача, які не підтримують classListвластивість, пов’язана сторінка MDN також містить прошивку для неї - хоча навіть shim не працюватиме у версіях Internet Explorer нижче IE 8.


Чистий відповідь і не винаходить колесо.
Marco Sulla

@Marco Sulla: це дійсно недолік, крім підтримки застарілого програмного забезпечення. .classListне є справжнім масивом, і такі методи, .indexOf(⋯)які не працюють на ньому. Це лише "об’єкт, схожий на масив", тоді як .className.split(/\s+/).indexOf(⋯)(з прийнятої відповіді) працює.
Incnis Mrsi

Ви можете легко перетворити будь-який ітерабельний у Arrayкористувальний [...iterable]абоArray.from(iterable)
Marco Sulla

142

Ось плагін jQuery, який поверне масив усіх класів, у яких є відповідні елементи

;!(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);

Використовуйте це як

$('div').classes();

У вашому випадку повертається

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

Ви також можете передати функцію методу, який потрібно викликати в кожному класі

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

Ось jsFiddle, яку я створив для демонстрації та тестування http://jsfiddle.net/GD8Qn/8/

Мінімізований Javascript

;!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);

Ідеально підходить для FullCalendar при копіюванні класів в атрибут className події.
Dan Power

78

Спробуйте це:

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

Він повертає масив усіх поточних класів елемента.


це набагато приємніше, що прийнята відповідь, чи є якісь причини не використовувати цей метод?
RozzA

5
Ну я не знаю. Але це правильний спосіб отримати властивість з елемента DOM. І "classList" - це таке властивість, яке дає вам масив класів css, застосованих до елемента.
П.Петков

@RozzA Можливо, тоді вона була недоступна? Але я б сказав, що це найбільш підходящий метод на даний момент, якщо ви не використовуєте jQuery, де просте .classListрішення - вам просто потрібно звернути увагу на невідповідності та / або відсутність підтримки браузера ..
Dennis98

@ Dennis98 гарний дзвінок, я іноді забуваю, як швидко з’явилися нові функції останнім часом. Я також зробив звичайний js, .classListвін працює досить добре в сучасних браузерах
RozzA

1
Зауважте, що classListвластивість не працює на IE 10/11 для елементів SVG (хоча вона працює для елементів HTML). Дивіться developer.mozilla.org/en-US/docs/Web/API/Element/classList
Métoule


7

Оновлення:

Як @Ryan Leonard правильно вказав, моя відповідь насправді не фіксує точку, яку я зробив самостійно ... Вам потрібно обрізати та видалити подвійні пробіли за допомогою (наприклад) string.replace (/ + / g, "") .. Або ви можете розділити el.className, а потім видалити порожні значення за допомогою (наприклад) arr.filter (Boolean).

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

або більш сучасний

const classes = element.classList;

Старий:

З усіма наведеними відповідями ви ніколи не забудете користувач .trim () (або $ .trim ())

Оскільки класи додаються та видаляються, може статися, що між рядком класу є кілька пробілів .. наприклад, 'class1 class2 class3' ..

Це перетвориться на ['class1', 'class2', '', '', '', 'class3'] ..

Коли ви використовуєте обробку, всі декілька пробілів видаляються ..


2
Це неправильно (а не відповідь). І String.trim (), і $ .trim () видаляють усі провідні та кінцеві пробіли, а решту рядка залишають у спокої. jsconsole.com /?% 22% 20% 20a% 20% 20b% 20% 20% 22.trim ()
Ryan Leonard

Ви навіть переглянули відповіді? Усі вбудовані рішення JS не перевіряли наявність пробільних та кінцевих пробілів, тим самим даючи несправний список класів, оскільки у масиві були б порожні класи .. jQuery робить те саме внутрішньо з
обрізкою,

2
Я бачив інші відповіді і погоджуюся, що пробіли слід видалити між іменами класів. Я вказував, що а) це має бути коментарем до інших рішень, оскільки це не повна відповідь b) .trim () не видаляє декілька пробілів, щоб досягти того, що вам потрібно.
Райан Леонард

1
Ви справді абсолютно правильні ... Вибачте за мій швидкий коментар. Він не видаляє пробіли між ... s.trim (). Замінити (/ + / g, "") або щось потрібно щоб видалити всі декілька пробілів між класами .. Поруч із цим, el.classList майже широко підтримується, виправляючи все, що я думаю ..
DutchKevv

1
ніяких проблем взагалі. На щастя, .classListце набагато чистіший підхід!
Райан Леонард

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

2
Це жахливе зловживання .map; використовувати, .eachякщо вам не потрібно .mapповернути значення. Розбиття на пробіли, а не будь-який пробіл, також порушено - дивіться мій коментар на stackoverflow.com/a/10159062/1709587 . Навіть якщо жоден із цих моментів не був правдивим, це не додає нічого нового на сторінку. -1!
Марк Амері

3

Можливо, це теж може вам допомогти. Я використовував цю функцію для отримання класів дитячого елемента.

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();
    });
}

У вашому випадку ви хочете, щоб клас doler_ipsum u може зробити так, як зараз calsses[2];.


2

Дякую за це - у мене була подібна проблема, оскільки я намагаюся програмно співвідносити об'єкти з ієрархічними іменами класів, хоча ці імена не обов'язково будуть відомі моєму сценарію.

У моєму сценарії я хочу, щоб <a>тег включав / вимикав довідковий текст, додаючи <a>тег [some_class]плюс клас toggle, а потім надаючи довідковий текст класу [some_class]_toggle. Цей код успішно знаходить пов'язані елементи за допомогою 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");}
    }
    });
} 

Спасибі Алан, я роблю щось подібне, я здивований, що не існує простішого способу зробити це.
Ерік Кігаті

- 1 - tl; dr, виходить на дотичну, що не має безпосереднього відношення до питання.
Марк Амері

2

Спробуйте це. Це дозволить отримати назви всіх класів з усіх елементів документа.

$(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);

});

Ось робочий приклад: https://jsfiddle.net/raju_sumit/2xu1ujoy/3/


1

У мене була подібна проблема стосовно елемента зображення типу. Мені потрібно було перевірити, чи елемент був певного класу. Спочатку я спробував:

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

але мені приємно "ця функція недоступна для цього елемента".

Тоді я оглянув мій елемент на досліднику DOM і побачив дуже приємний атрибут, який я міг би використовувати: className. Він містив назви всіх класів мого елемента, розділених порожніми пробілами.

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

Як тільки ви це отримаєте, просто розділіть рядок, як зазвичай.

У моєму випадку це спрацювало:

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

Я припускаю, що це буде працювати з іншими типами елементів (крім img).

Сподіваюся, це допомагає.


0

javascript надає атрибут classList для елемента вузла в dom. Просто за допомогою

  element.classList

поверне об’єкт форми

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

Об'єкт має такі функції, як містити, додавати, видаляти, які ви можете використовувати


Менший дублікат stackoverflow.com/a/5457148/1709587, який був розміщений за 3 роки до вас; -1.
Марк Амері

-3

Трохи запізнюється, але використання функції exte () дозволяє викликати "hasClass ()" на будь-якому елементі, наприклад:
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
У цьому не було питання.
Томаш

5
Також jQuery вбудовував цю функцію з версії 1.2.
Андрій

-3

Питання в тому, що призначений робити Jquery.

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

І чому ніхто не дав .find () як відповідь?

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

Існує також ClassList для веб-переглядачів, які не є IE:

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

3
- 1; серед інших проблем, перші два фрагменти коду не пов'язані із заданим запитанням, а ваш остаточний фрагмент - це синтаксична помилка.
Марк Амері

-4

Ось ви й просто підстежили відповідь читального квадрата , щоб повернути масив усіх класів:

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;
}

Передайте функцію jQuery до функції, щоб зразок виклику був:

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

3
Навіщо перебирати через масив classList, додавати всі елементи до масиву класів та повертати масив класів? Просто повернення classList повинно зробити той же трюк, правда?
Martijn

Ні. Оскільки ми маємо на увазі ситуацію, коли для одного і того ж елемента існує багато класів. Якби це було так просто, ми не були б тут на цій темі :)
Грегра

8
Цей потік стосується повернення списку класів, і це просто повернення $(elem).attr('class').split(/\s+/). Можливо, я помиляюся, але не бачу жодної причини перебирати колекцію, копіювати вміст у нову колекцію та повертати цю нову колекцію.
Martijn

-4

Я знаю, це старе питання, але все ж.

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

var className=".dolor_spec" //dynamic

Якщо ви хочете маніпулювати елементом

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

Якщо ви хочете перевірити, чи має елемент клас

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

якщо кілька класів

//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
Жоден із цих фрагментів не стосується заданого питання; -1.
Марк Амері
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.