Получить список классов для элемента с помощью jQuery

696

Есть ли способ в jQuery перебрать или назначить массиву все классы, назначенные элементу?

бывший.

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

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

4
  • Если вы не знаете имя класса в то время, что мешает вам использовать hasClass (), как вы собираетесь узнать, какой из них в массиве? doomspork 4 авг.
  • Я разрабатываю форму, в которой я выполняю предварительную проверку с помощью jQuery. Я добавляю идентификатор входного элемента в список классов div с ошибкой, если он сгенерирован. Затем я делаю возможным щелкнуть div с ошибкой, чтобы сфокусировать ошибочный элемент ввода. Этот сценарий будет использоваться более чем для одной формы. Поэтому я не хочу жестко кодировать идентификаторы в скрипте. Buggabill 4 авг.
  • 1
    Хорошо, я понимаю, почему вы не хотите жестко кодировать. Но если вы посмотрите на пример redsquare, вы увидите, что вам нужно жестко закодировать someClass в блоке if. В любом случае вы можете добиться этого с помощью переменной. doomspork 4 авг.
  • Вместо использования атрибута class у вас может быть переменная списка ошибок внутри вашего пространства имен, которая содержит ссылки DOM на элементы с ошибками. Таким образом устраняется необходимость извлекать список атрибутов каждый раз, перебирать его, находить элемент DOM и фокусировать его. doomspork 04 авг.
759

Вы можете использовать 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
    }
});
9
  • 4
    это именно то, что я сделал, но я не был уверен, есть ли в функции jQuery сборка, которая дала вам коллекцию классов. Sander 4 авг.
  • 39
    К вашему сведению: jQuery использует className.split (/ \ s + /)kͩeͣmͮpͥ ͩ 8 фев '10 в 11:56
  • 72
    Добавьте плагин jQuery самостоятельно:$.fn.classList = function() {return this[0].className.split(/\s+/);};ripper234 9 марта '12 в 17:45
  • 2
    или тогда вы могли бы: if ($.inArray("someclass",classList)>=0) { /* hasClass someclass*/ }sambomartin 19 окт.
  • Здесь не эксперт по javascript. Можете ли вы сказать мне, лучше ли split (/ \ s + /), чем просто выполнение split ("")? У меня это работает так же в FF23 / Chrome28 / IE8. Roberto Linares 27 сен.
314

Почему просто никто не перечислил.

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

РЕДАКТИРОВАТЬ: Разделите /\s+/вместо того, ' 'чтобы исправить возражение @MarkAmery . (Спасибо @ YashaOlatoto .)

12
  • 6
    Это часть принятого ответа ... Мне нужны были все классы, которые были применены к элементу. Buggabill 17 апр '12 в 12:26
  • 54
    Потому что это неправильно! Классы могут быть разделены пробелами любого типа (например, вы можете перенести длинный атрибут класса в свой HTML-код на несколько строк), но этот ответ не учитывает это. Попробуйте вставить $('<div class="foo bar baz">').attr("class").split(' ')в консоль браузера (там есть символ табуляции); вы получите ["foo", "bar baz"]вместо правильного списка классов ["foo", "bar", "baz"]. Mark Amery 17 дек.
  • 2
    @MarkAmery права. Если бы у вас был a class="foo <lots of spaces here> bar", вы бы получили массив с пустыми строковыми элементами. Jacob van Lingen 22 сен.
  • 4
    Я думаю, что в 99% случаев это решение эффективно, т.е. при условии, что вы управляете HTML. Я не могу придумать, по какой причине нам нужно было бы поддерживать возможность табуляции или нескольких пробелов между именами классов, даже если стандарты HTML позволяют это. Gordon Rouse 20 сен '17 в 3:46
  • 5
    @GordonRouse - это обычное дело, вкрадывающееся в список классов, особенно если какая-то логика выписывает список классов. Eric 18 апр '18 в 13:10
158

При поддержке браузеров вы можете использовать classListсвойство элементов DOM .

$(element)[0].classList

Это объект в виде массива, в котором перечислены все классы, которые имеет элемент.

Если вам нужно поддерживать старые версии браузеров, которые не поддерживают это classListсвойство, связанная страница MDN также включает в себя прокладку для него, хотя даже прокладка не будет работать в версиях Internet Explorer ниже IE 8.

2
  • 1
    @Marco Sulla: у этого действительно есть недостаток, кроме поддержки устаревшего программного обеспечения. .classListне является истинным массивом, и такие методы, которые с ним .indexOf(⋯)не работают. Это только «объект, подобный массиву», тогда как .className.split(/\s+/).indexOf(⋯)(из принятого ответа) работает. Incnis Mrsi 28 янв.
  • 2
    Вы можете легко преобразовать любую итерацию в Arrayusing [...iterable]илиArray.from(iterable)Marco Sulla 28 янв.
141

Вот плагин 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);
1
  • Идеально подходит для FullCalendar при копировании классов в атрибут className события. Dan Power 27 авг.
87

Вы должны попробовать это:

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

Он возвращает список всех текущих классов элемента.

9
  • это намного аккуратнее, чем принятый ответ, есть ли причина не использовать этот метод? RozzA 7 мая '16 в 0:45
  • 6
    Ну не знаю. Но это правильный способ получить свойство от элемента DOM. И "classList" - это такое свойство, которое дает вам массив классов css, примененных к элементу. P.Petkov 9 мая '16 в 21:14
  • @RozzA Может быть, тогда этого не было? Но я бы сказал, что это наиболее подходящий метод на данный момент, если вы не используете jQuery, где .classListрешение является простым - вам просто нужно обратить внимание на несоответствия и / или отсутствие поддержки браузера ..Dennis98 1 сен '16 в 14:58
  • @ Dennis98 хороший звонок, иногда я забываю, как быстро появились новые функции в последнее время. Я также написал простой js, .classListон неплохо работает в современных браузерахRozzA 5 сен '16 в 7:01
  • 3
    Обратите внимание, что это classListсвойство не работает в IE 10/11 для элементов SVG (хотя оно работает для элементов HTML). См. Developer.mozilla.org/en-US/docs/Web/API/Element/classListMétoule 19 июл.
17
var classList = $(element).attr('class').split(/\s+/);
$(classList).each(function(index){

     //do something

});
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'] ..

Когда вы используете обрезку, все несколько пробелов удаляются.

5
  • 2
    Это неверно (и не ответ). И String.trim (), и $ .trim () удаляют все начальные и конечные пробелы и оставляют остальную часть строки в покое. jsconsole.com /?% 22% 20% 20a% 20% 20b% 20% 20% 22.trim ()Ryan Leonard 24 окт.
  • Вы даже посмотрели на ответы? Все собственные JS-решения не проверяли наличие начальных и конечных пробелов, что давало неверный список классов, поскольку в массиве были бы пустые классы. JQuery делает то же самое внутренне с обрезкой, когда он читает классыDutchKevv 24 окт.
  • 2
    Я видел другие ответы и согласен с тем, что между именами классов следует удалить пробелы. Я указывал, что а) это должен быть комментарий к другим решениям, поскольку это не полный ответ б) .trim () не удаляет несколько пробелов для достижения того, что вам нужно. Ryan Leonard 24 окт.
  • 1
    Вы действительно совершенно правы ... Извините за мой слишком быстрый комментарий .. Он не удаляет пробелы между ... s.trim (). Replace (/ + / g, "") или что-то может понадобиться чтобы удалить все множественные пробелы между классами .. Кроме того, el.classList почти широко поддерживается, и я полагаю, что все это исправляет ..DutchKevv 19 ноя '17 в 0:42
  • 1
    совершенно никаких проблем. К счастью, .classListэто гораздо более чистый подход! Ryan Leonard 25 ноя '17 в 4:27
7
$('div').attr('class').split(' ').each(function(cls){ console.log(cls);})
1
  • 2
    Это ужасное злоупотребление .map; используйте, .eachесли вам не нужно .mapвозвращаемое значение. Разделение на пробелы, а не на пробелы также нарушено - см. Мой комментарий на stackoverflow.com/a/10159062/1709587 . Даже если ни один из этих пунктов не соответствует действительности, это не добавляет на страницу ничего нового. -1! Mark Amery 17 дек.
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, и вы можете сделать это сейчас 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");}
    }
    });
} 
2
  • Спасибо, Алан, я делаю нечто подобное, я удивлен, что нет более простого способа сделать это. Eric Kigathi 31 янв.
  • - 1 - tl; dr, уходит по касательной, не имеющей прямого отношения к вопросу. Mark Amery 17 дек.
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

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

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

но я получил приятное сообщение «эта функция недоступна для этого элемента».

Затем я проверил свой элемент в проводнике DOM и увидел очень хороший атрибут, который я мог бы использовать: className. Он содержал имена всех классов моего элемента, разделенные пробелами.

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

Как только вы получите это, просто разделите строку как обычно.

В моем случае это сработало:

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

Я предполагаю, что это будет работать с другими типами элементов (кроме img).

Надеюсь, это поможет.

1

Вы можете следить примерно за этим.

$('#elementID').prop('classList').add('yourClassName')
$('#elementID').prop('classList').remove('yourClassName')
0

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

  element.classList

вернет объект формы

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

У объекта есть такие функции, как "содержит", "добавить", "удалить", которые вы можете использовать.

1
-3

Немного поздно, но использование функции extend () позволяет вызывать 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);
2
  • 10
    Вопрос был не в этом. Tomas 23 марта '11 в 13:18
  • 5
    Кроме того, в jQuery, начиная с версии 1.2, эта функция встроена. Andrew 15 сен.
-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
1
  • 3
    - 1; среди прочего, первые два фрагмента кода не связаны с заданным вопросом, а последний фрагмент представляет собой синтаксическую ошибку. Mark Amery 17 дек.