Как получить элемент по классу в JavaScript?

226

Я хочу заменить содержимое элемента html, поэтому для этого я использую следующую функцию:

function ReplaceContentInContainer(id,content) {
   var container = document.getElementById(id);
   container.innerHTML = content;
}

ReplaceContentInContainer('box','This is the replacement text');

<div id='box'></div>

Вышеописанное прекрасно работает, но проблема в том, что у меня есть несколько HTML-элементов на странице, содержимое которых я хочу заменить. Поэтому я не могу использовать идентификаторы, но вместо этого классы. Мне сказали, что javascript не поддерживает встроенный элемент get любого типа с помощью функции класса. Так как же можно изменить приведенный выше код, чтобы он работал с классами вместо идентификаторов?

PS Я не хочу использовать jQuery для этого.

Тейлор
источник

Ответы:

198

Этот код должен работать во всех браузерах.

function replaceContentInContainer(matchClass, content) {
    var elems = document.getElementsByTagName('*'), i;
    for (i in elems) {
        if((' ' + elems[i].className + ' ').indexOf(' ' + matchClass + ' ')
                > -1) {
            elems[i].innerHTML = content;
        }
    }
}

Это работает путем циклического перебора всех элементов в документе и поиска их списка классов matchClass. Если совпадение найдено, содержимое заменяется.

Пример jsFiddle с использованием Vanilla JS (т.е. без фреймворка)

Рэнди Дев
источник
5
+1 - Хорошая ловушка с пробелами, я всегда забываю это делать ... собираюсь украсть это для моего ответа;) хотя класс - зарезервированное слово в javascript; Вы не должны использовать его для имени переменной, хотя это действительно не приносит никакого вреда (пока).
Дагг Наббит
1
@ Нет с этой функцией, вам не нужно иметь контент внутри элемента, который вы хотите заменить. У вас может быть строка или она может быть пустой. В любом случае, при вызове функции там внезапно появится текст замены.
Тейлор
4
Andrew, @no - Использование classв качестве имени переменной в Safari не работает, поэтому в настоящее время оно оказывает влияние.
user113716
4
Массив, возвращаемый getElementsBytagName, также имеет свойство length, для которого также выполняется тест className / indexOf. Хотя в этом случае это не проблема, обычный цикл for будет более правильным.
Вольфганг Стенгель
1
вместо indexOf с пробелами сохранение elems[i].className, скажем var cnи использование cn && cn.match(new RegExp("(^|\\s)" + matchClass + "(\\s|$)"))будет работать лучше, поскольку оно соответствует любому пробелу (пробел, неразрывный пробел, табуляция и т. д.), а также позволяет сопоставить имена первого / последнего классов. Пример: jsfiddle.net/AXdtH/1636
Supuhstar
178

Конечно, все современные браузеры теперь поддерживают следующий более простой способ:

var elements = document.getElementsByClassName('someClass');

но имейте в виду, что он не работает с IE8 или раньше. Смотрите http://caniuse.com/getelementsbyclassname

Кроме того, не все браузеры будут возвращать чистоту, NodeListкак они должны.

Вам, вероятно, все еще лучше использовать вашу любимую библиотеку кросс-браузер.

Холодно холодно
источник
Для IE8 вы можете использовать querySelectorAll.
Гра Дабл
109
document.querySelectorAll(".your_class_name_here");

Это будет работать в «современных» браузерах, которые реализуют этот метод (IE8 +).

function ReplaceContentInContainer(selector, content) {
  var nodeList = document.querySelectorAll(selector);
  for (var i = 0, length = nodeList.length; i < length; i++) {
     nodeList[i].innerHTML = content;
  }
}

ReplaceContentInContainer(".theclass", "HELLO WORLD");

Если вы хотите обеспечить поддержку старых браузеров, вы можете загрузить автономный механизм выбора, такой как Sizzle (4KB mini + gzip) или Peppy (10K mini), и использовать его, если не найден собственный метод querySelector.

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

Кристиан Санчес
источник
@ Тейлор: Я думаю, что это работает в IE8 (не уверен на 100% - слишком ленив, чтобы гуглить). Несмотря на это, я добавил некоторую информацию о обратной совместимости, используя сторонние селекторные движки.
Кристиан Санчес
18
document.querySelectorработает в IE8 и выше: caniuse.com/queryselector
Zeke
26

Простой и легкий способ

var cusid_ele = document.getElementsByClassName('custid');
for (var i = 0; i < cusid_ele.length; ++i) {
    var item = cusid_ele[i];  
    item.innerHTML = 'this is value';
}
КТА
источник
6

Я удивлен, что нет ответов, использующих регулярные выражения. Это в значительной степени ответ Эндрю , использующий RegExp.testвместо String.indexOf, так как, кажется, он работает лучше для нескольких операций, согласно тестам jsPerf .
Это также, кажется, поддерживается на IE6 .

function replaceContentInContainer(matchClass, content) {
    var re = new RegExp("(?:^|\\s)" + matchClass + "(?!\\S)"),
        elems = document.getElementsByTagName('*'), i;
    for (i in elems) {
        if (re.test(elems[i].className)) {
            elems[i].innerHTML = content;
        }
    }
}

replaceContentInContainer("box", "This is the replacement text.");

Если вы часто ищете один и тот же класс (ы), вы можете улучшить его, сохранив (предварительно скомпилированные) регулярные выражения в другом месте и передав их непосредственно в функцию вместо строки.

function replaceContentInContainer(reClass, content) {
    var elems = document.getElementsByTagName('*'), i;
    for (i in elems) {
        if (reClass.test(elems[i].className)) {
            elems[i].innerHTML = content;
        }
    }
}

var reBox = /(?:^|\s)box(?!\S)/;
replaceContentInContainer(reBox, "This is the replacement text.");
afsantos
источник
4

Это должно работать практически в любом браузере ...

function getByClass (className, parent) {
  parent || (parent=document);
  var descendants=parent.getElementsByTagName('*'), i=-1, e, result=[];
  while (e=descendants[++i]) {
    ((' '+(e['class']||e.className)+' ').indexOf(' '+className+' ') > -1) && result.push(e);
  }
  return result;
}

Вы должны быть в состоянии использовать это так:

function replaceInClass (className, content) {
  var nodes = getByClass(className), i=-1, node;
  while (node=nodes[++i]) node.innerHTML = content;
}
Дагг Наббит
источник
3

var elems = document.querySelectorAll('.one');

for (var i = 0; i < elems.length; i++) {
    elems[i].innerHTML = 'content';
};

Роджер Каусто
источник
4
Это не совсем ответ. Пожалуйста, попробуйте объяснить ваш код . Кроме того, это в основном более компактная версия другого ответа на этот вопрос, который был опубликован 5 лет назад.
helmbert
Я не знаю, в чем проблема. Этот ответ в порядке. Там нет комментариев ... и что? Это не золотое правило. А что вы хотите прокомментировать здесь? И читаемый код?
AntiCZ
3

Я предполагаю, что это было недопустимым вариантом, когда об этом изначально спрашивали, но теперь вы можете использовать document.getElementsByClassName('');. Например:

var elements = document.getElementsByClassName(names); // or:
var elements = rootElement.getElementsByClassName(names);

Смотрите документацию MDN для получения дополнительной информации.

thornjad
источник
0

Я думаю что-то вроде:

function ReplaceContentInContainer(klass,content) {
var elems = document.getElementsByTagName('*');
for (i in elems){
    if(elems[i].getAttribute('class') == klass || elems[i].getAttribute('className') == klass){
        elems[i].innerHTML = content;
    }
}
}

должно сработать

KeatsKelleher
источник
1
если у вас есть только несколько элементов на вашей странице, в противном случае это решение O (N)
jwl
getAttribute ('class'), кажется, работает во всех, кроме IE, затем getAttribute ('className') работает в IE
KeatsKelleher
0

JQuery справляется с этим легко.

let element = $(.myclass);
element.html("Some string");

Он изменяет все элементы .myclass на этот текст.

Даниэль Хойфёдт
источник
PS: в вопросе говорится: «Я не хочу использовать для этого jQuery».
Джулиан
Хорошо, я этого не видел.
Даниэль Хойфёдт
-15

Когда некоторым элементам не хватает идентификатора, я использую jQuery следующим образом:

$(document).ready(function()
{
    $('.myclass').attr('id', 'myid');
});

Это может быть странное решение, но, возможно, кто-то найдет его полезным.

Кротек
источник
3
Если есть несколько элементов с классом myclass, все они получат идентификатор myid, но идентификаторы должны быть уникальными! Более того, OP явно говорит, чтобы избежать jQuery.
Ориоль
1
Нетрудно добавить предложение foreach () и идентификатор приращения, если у вас есть несколько элементов одного класса. Я добавил это решение как альтернативу для тех, кто может использовать jQuery. ОП уже получил кучу подходящих ответов :-)
The Krotek