Получить все элементы в HTML-документе с определенным классом CSS

Какой лучший способ получить массив всех элементов в html-документе с определенным классом CSS с использованием javascript?

Здесь прямо сейчас не разрешены фреймворки javascript, такие как jQuery, и я мог бы зацикливать все элементы и проверять их вручную. Я надеюсь на что-нибудь более элегантное.

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
39
0
98 586
10
Перейти к ответу Данный вопрос помечен как решенный

Ответы 10

Вы можете включить функцию getElementsByClass или использовать селектор jQuery.

Обновлено:выполнение, упомянутый @ Shog9, вероятно, лучше, чем это выше.

Класса CSS не существует. В CSS есть наборы правил и селекторы (включая селектор классов).

Вы имеете в виду HTML-класс? Обычный способ - перебрать каждый элемент в документе (using document.getElementsByTagName('*') (для эффективности используйте определенное имя тега, если вы знаете, что класс будет применяться только к элементам определенного типа) и протестировать свойство className каждого (отмечая, что свойство содержит список имен классов, разделенных пробелами, а не одно имя класса).

В ряде библиотек (таких как jQuery или Юй) есть функции для этого.

Вы имеете в виду селектор CSS? Это становится более сложным, и почти наверняка лучше обратиться к библиотеке. Опять же, jQuery или Юй - достойный выбор.

1) Получить все элементы в документе (document.getElementsByTagName ('*'))
2) Сопоставьте регулярное выражение с атрибутом className элемента для каждого элемента

Почему это было отклонено? Это отлично подходит для решения, полностью основанного на JavaScript.

Jason Bunting 17.10.2008 01:37

Согласовано. Похоже, что в SO существует предвзятость JS-фреймворка до такой степени, что предложения чистого Javascript смотрят свысока. Рекомендовать и указывать на решения в рамках фреймворков - это нормально, но и автономные решения Javascript - тоже.

AnthonyWJones 17.10.2008 01:51

Конечно, проповедовать хору - мне нравится использовать фреймворк, но факт в том, что не все хотят его использовать или могут. Я думаю, что некоторые из тех, кто использует фреймворки, не знают достаточно, чтобы знать, как это сделать без него, поэтому они видят эти ответы и понижают их из-за невежества, гордости или чего-то подобного.

Jason Bunting 17.10.2008 01:52

@ Джейсон: В большинстве случаев я бы согласен, но в этом случае существует множество существующих реализаций, доработанных и отточенных за последние несколько лет, и поэтому написание собственного просто кажется мазохистским - как написание собственного типа процедура, когда qsort () работает нормально. (Я не голосовал против)

Shog9 17.10.2008 02:10
Ответ принят как подходящий

Приведенному ниже ответу сейчас исполнилось четыре года, поэтому стоит отметить, что поддержка getElementsByClassName() в собственном браузере стала лучше много. Но если вам необходимо поддерживать старые браузеры, тогда ...

Используйте тот, который уже был написан. Большинство основных JS-библиотек включают одну в той или иной форме, но если вы не используете одну из них, я могу порекомендовать отличную реализацию Роберта Наймана:

http://code.google.com/p/getelementsbyclassname/
http://www.robertnyman.com/2008/05/27/the-ultimate-getelementsbyclassname-anno-2008/

Есть слишком много способов сделать эту (концептуально простую) подпрограмму медленный и глючный, чтобы оправдать написание вашей собственной реализации на данном этапе.

Используйте jquery, удобнее не бывает.

$ (". класс") или же $ (". theclass"), makeArray (), если вам нужен собственный массив JS

Просто чтобы продолжить, я основал свой код на реализации Роберта Наймана, опубликованной Shog9, но немного отошел от его точной версии по трем причинам:

  1. Он позволил вам выбрать корневой элемент и тип тега для фильтрации результатов. Мне эта функция не нужна, поэтому, удалив ее, я смог значительно упростить код.
  2. Первое, что делает его код, - это проверяет, существует ли уже рассматриваемая функция, и если да, он все равно предоставляет свою собственную реализацию. Это просто казалось ... странным. Я понимаю, что он добавлял функциональность к оригиналу, но опять же: я не использую эти функции.
  3. Я хотел добавить немного синтаксического сахара, чтобы иметь возможность называть это так, как я бы назвал document.getElementById() или document.getElementsByTagName().

Обратите внимание, что я по-прежнему в основном полагался на его код. Очевидно, что его навыки работы с javascript намного превосходят мои собственные. Я пытался исключить некоторые избыточные переменные, но это все.

Имея это в виду, вот что у меня получилось (кажется для работы в IE6, IE7, Firefox 3 и Chrome см. новую заметку в конце):

 if (!document.getElementsByClassName)
    document.getElementsByClassName = function (className)
{
    var classes = className.split(" ");
    var classesToCheck = "";
    var returnElements = [];
    var match, node, elements;

    if (document.evaluate)
    {    
        var xhtmlNamespace = "http://www.w3.org/1999/xhtml";
        var namespaceResolver = (document.documentElement.namespaceURI === xhtmlNamespace)? xhtmlNamespace:null;

        for(var j=0, jl=classes.length; j<jl;j+=1)
            classesToCheck += "[contains(concat(' ', @class, ' '), ' " + classes[j] + " ')]"; 

        try
        {
            elements = document.evaluate(".//*" + classesToCheck, document, namespaceResolver, 0, null);
        }
        catch(e)
        {
            elements = document.evaluate(".//*" + classesToCheck, document, null, 0, null);
        }

        while ((match = elements.iterateNext()))
            returnElements.push(match);
    }
    else
    {
        classesToCheck = [];
        elements = (document.all) ? document.all : document.getElementsByTagName("*");

        for (var k=0, kl=classes.length; k<kl; k+=1)
            classesToCheck.push(new RegExp("(^|\\s)" + classes[k] + "(\\s|$)"));

        for (var l=0, ll=elements.length; l<ll;l+=1)
        {
            node = elements[l];
            match = false;
            for (var m=0, ml=classesToCheck.length; m<ml; m+=1)
            {
                match = classesToCheck[m].test(node.className);
                if (!match) break;
            }
            if (match) returnElements.push(node);
        } 
    }
    return returnElements;
}

Обновлять:
Одно новое примечание по этому поводу. С тех пор я перечитал примечания к исходной реализации и теперь понимаю, что мой код может упасть в случае, если существующий браузер имеет собственную реализацию, потому что реализации по умолчанию возвращают список узлов, в котором он возвращает массив. Это включает в себя более свежие браузеры Firefox, Safari и Opera. В большинстве случаев это не имеет значения, но в некоторых ситуациях может. Это объясняет пункт 2 из списка выше.

Это означает, что хотя мой код технически работает везде, он может привести к слегка различающимся (читай: трудным для отладки) поведением в разных местах, а это нехорошо. Я должен исправляю это, чтобы либо также вернуть список узлов, либо переопределить предоставленный метод для возврата массива (что и сделал оригинал). Вероятно, первое было бы проще, но второе - лучше.

Однако на данный момент он работает в среде локальной интрасети (почти все IE), поэтому пока я оставлю исправление в качестве упражнения для читателя.

Имейте в виду, что по крайней мере в FF3 уже есть собственная реализация getElementsByClassName afaik.

Если вы собираетесь реализовать собственное решение, возможно, вам стоит попытаться найти решение xpath, поскольку все современные браузеры имеют встроенную поддержку xpath.

Ага: Я уже обновляю свой пост, но это займет немного времени, разложит на несколько правок.

Joel Coehoorn 06.11.2008 21:05

При использовании фреймворка все они имеют выбор с помощью селекторов CSS. Иначе.

var getElementsByClassName = function(cls, sc){
    //Init
    var elements, i, results = [], curClass;  

    //Default scope is document
    sc = sc || document;

    //Get all children of the scope node
    elements = sc.getElementsByTagName('*');
    for( i=0; i < elements.length; i++ ){
        curClass = elements[i].getAttribute('class');
        if (curClass != null){
            curClass = curClass.split(" ");
            for( j=0; j < curClass.length; j++){
                if (curClass[j] === cls){
                    results.push( elements[i] );
                    break;
                }
            }
        }
    }

    return results;
};

Просто написал это прямо сейчас, специально для вас. :) Смело пользуйтесь.

Старый вопрос, но ничего страшного. Единственная проблема здесь в том, что если у вас есть такие классы, как «navarea-top» и «navarea», и вы просто ищете «navarea», вы также найдете все элементы «navarea-top».

Joel Coehoorn 14.05.2009 21:16

Правда. Чтобы расширить его, можно получить атрибут class и использовать для проверки регулярное выражение вместо indexOf.

Dmitri Farkov 14.05.2009 21:18

Зафиксированный. :) Спасибо за ваш отзыв

Dmitri Farkov 14.05.2009 21:21

Если вы хотите что-то сделать для всех элементов с одинаковым идентификатором в документе. Хотя это просто, но иногда разум не дает зеленых сигналов

var x = document.getElementById(elementid);
while(x){
document.removechild(x);
x = document.getElementById(elementid);
}

Если у вас есть несколько элементов с одним и тем же идентификатором, вы делаете что-то не так.

Joel Coehoorn 12.11.2010 18:24

@ shog9, @ user28742, @bdukes - Я занимаюсь специальной разработкой в ​​SharePoint для модульной вещи (определение настраиваемого поля), я надеюсь, что ее можно будет повторно использовать на многих сайтах.

Поскольку я не могу заранее знать, будет ли на каком-либо сайте SharePoint доступная jQuery или какая-либо другая библиотека --- мне все еще нужно писать вещи в необработанном javascript, чтобы я мог быть уверен, что функциональность, которую я попытка достичь будет стоять сама по себе.

Спасибо Дмитрию за вашу конкретную реализацию. Достаточно коротко для моих целей.

В других недавних попытках мне пришлось модифицировать магазин электронной коммерции (по выбору моего клиента), и некоторые из моих попыток встроить в него jQuery фактически противоречили тем пользовательским библиотекам, которые они использовали ранее. Я мог бы проявить настойчивость и найти способ внедрить jQuery в их проприетарную систему ... или ... даже быстрее ... просто написать какой-нибудь старый добрый javascript.

Библиотеки - НЕ ВСЕГДА ЛУЧШИЙ ОТВЕТ !!!!!!!!!!!!!!!!

(а я люблю jQuery больше, чем свою бабушку)

Проголосовали за: Технически это не ответ на этот вопрос, но это хороший ответ для людей, которые настаивают на том, чтобы добавить свою любимую библиотеку в эти вопросы.

AnthonyVO 15.06.2012 20:02

грустная бабушка, мне ее жалко

EaterOfCode 25.01.2013 17:08

Другие вопросы по теме