Jak uzyskać element według klasy w JavaScript?

226

Chcę zastąpić zawartość w elemencie HTML, więc używam do tego następującej funkcji:

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

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

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

Powyższe działa świetnie, ale problem polega na tym, że na stronie mam więcej niż jeden element HTML, który chcę zastąpić zawartością. Nie mogę więc używać identyfikatorów zamiast klas. Powiedziano mi, że javascript nie obsługuje żadnego typu wbudowanego elementu get według funkcji klasy. Jak więc zmienić powyższy kod, aby działał z klasami zamiast z identyfikatorami?

PS Nie chcę do tego używać jQuery.

Taylor
źródło

Odpowiedzi:

198

Ten kod powinien działać we wszystkich przeglądarkach.

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

Działa poprzez zapętlanie wszystkich elementów w dokumencie i wyszukiwanie ich listy klas matchClass. Jeśli zostanie znalezione dopasowanie, zawartość zostanie zastąpiona.

Przykład jsFiddle, używając Vanilla JS (tj. bez frameworka)

Randy the Dev
źródło
5
+1 - Dobry chwyt ze spacjami, zawsze zapominam o tym ... zamierzam ukraść to dla mojej odpowiedzi;) klasa jest jednak zarezerwowanym słowem w javascript; nie powinieneś używać go do nazwy zmiennej, nawet jeśli tak naprawdę nie wyrządza to żadnej szkody (jeszcze).
Dagg Nabbit
1
@no z tą funkcją nie musisz mieć żadnej zawartości wewnątrz elementu, który chcesz zastąpić. Możesz mieć tam łańcuch lub możesz go opróżnić. Tak czy inaczej tekst zastępczy pojawi się nagle po wywołaniu funkcji.
Taylor
4
Andrew, @no - Używanie classjako nazwy zmiennej nie działa w Safari, więc obecnie ma wpływ.
user113716,
4
Tablica zwrócona przez getElementsBytagName ma również właściwość length, dla której następnie wykonuje się również test className / indexOf. Chociaż w tym przypadku nie stanowi to problemu, regularna pętla for byłaby bardziej poprawna.
Wolfgang Stengel
1
zamiast indexOf ze spacjami, zapisywanie elems[i].classNamew, mówienie var cni używanie cn && cn.match(new RegExp("(^|\\s)" + matchClass + "(\\s|$)"))działałoby lepiej, ponieważ pasuje do dowolnej białej spacji (spacja, spacja nieprzekraczająca, tab, itp.), jednocześnie umożliwiając dopasowanie nazw klas pierwszych / ostatnich. Przykład: jsfiddle.net/AXdtH/1636
Supuhstar
178

Oczywiście wszystkie nowoczesne przeglądarki obsługują teraz następującą prostszą metodę:

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

ale ostrzegam, że nie działa z IE8 ani wcześniej. Zobacz http://caniuse.com/getelementsbyclassname

Ponadto, nie wszystkie przeglądarki zwrócą czysty sposób, w NodeListjaki powinny.

Prawdopodobnie nadal lepiej jest korzystać ze swojej ulubionej biblioteki w różnych przeglądarkach.

Zimno zimno
źródło
Do IE8 możesz użyć querySelectorAll.
Gras Double
109
document.querySelectorAll(".your_class_name_here");

Będzie to działać w „nowoczesnych” przeglądarkach, które implementują tę metodę (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");

Jeśli chcesz zapewnić obsługę starszych przeglądarek, możesz załadować autonomiczny silnik wyboru, taki jak Sizzle (4KB mini + gzip) lub Peppy (10K mini) i wrócić do niego, jeśli nie zostanie znaleziona natywna metoda querySelector.

Czy przesadne jest ładowanie silnika selektora tylko po to, aby uzyskać elementy o określonej klasie? Prawdopodobnie. Jednak skrypty nie są aż tak duże i silnik selektora może okazać się przydatny w wielu innych miejscach skryptu.

Cristian Sanchez
źródło
@Taylor: Myślę, że działa w IE8 (nie jestem w 100% pewien - zbyt leniwy, aby google go). Niezależnie od tego, dodałem kilka informacji dotyczących kompatybilności wstecznej przy użyciu silników wyboru innych firm.
Cristian Sanchez,
18
document.querySelectordziała w IE8 i nowszych: caniuse.com/queryselector
Zeke
26

Prosty i łatwy sposób

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';
}
kta
źródło
6

Dziwi mnie, że nie ma odpowiedzi przy użyciu wyrażeń regularnych. Jest to w zasadzie odpowiedź Andrew , która używa RegExp.testzamiast String.indexOf, ponieważ wydaje się, że działa lepiej dla wielu operacji, zgodnie z testami jsPerf .
Wydaje się również, że jest obsługiwany w 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.");

Jeśli często poszukujesz tych samych klas, możesz je ulepszyć, przechowując (wstępnie skompilowane) wyrażenia regularne w innym miejscu i przekazując je bezpośrednio do funkcji zamiast ciągu.

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
źródło
4

Powinno to działać w prawie każdej przeglądarce ...

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

Powinieneś być w stanie używać go w następujący sposób:

function replaceInClass (className, content) {
  var nodes = getByClass(className), i=-1, node;
  while (node=nodes[++i]) node.innerHTML = content;
}
Dagg Nabbit
źródło
3

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

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

Roger Causto
źródło
4
To naprawdę nie jest odpowiedź. Spróbuj wyjaśnić swój kod . Co więcej, jest to w zasadzie bardziej zwarta wersja innej odpowiedzi na to pytanie, która została opublikowana 5 lat temu.
helmbert
Nie wiem na czym polega problem. Ta odpowiedź jest w porządku. Nie ma komentarza ... i co? To nie jest złota zasada. A co chcesz tutaj skomentować? A czy to jest czytelny kod?
AntiCZ
3

Zakładam, że nie była to prawidłowa opcja, kiedy pierwotnie o to pytano, ale teraz możesz jej użyć document.getElementsByClassName('');. Na przykład:

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

Więcej informacji znajduje się w dokumentacji MDN .

thornjad
źródło
0

Myślę, że coś takiego:

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

pracowałbym

KeatsKelleher
źródło
1
jeśli masz tylko garść elementów na swojej stronie, w przeciwnym razie jest to rozwiązanie O (N)
jwl
getAttribute („klasa”) wydaje się działać we wszystkich oprócz IE, następnie getAttribute („klasaNazwa”) działa w IE
KeatsKelleher
0

jQuery radzi sobie z tym łatwo.

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

Zmienia wszystkie elementy .myclass na ten tekst.

Daniel Høifødt
źródło
PS: pytanie brzmi: „Nie chcę do tego używać jQuery”.
Julian
Ok, nie widziałem tego.
Daniel Høifødt
-15

Kiedy niektóre elementy nie mają identyfikatora, używam jQuery w następujący sposób:

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

To może być dziwne rozwiązanie, ale może ktoś uzna to za przydatne.

Krotek
źródło
3
Jeśli istnieje wiele elementów z klasą myclass, wszystkie otrzymają identyfikator myid, ale identyfikatory powinny być unikalne! Co więcej, OP wyraźnie mówi, aby unikać jQuery.
Oriol
1
Dodanie klauzuli foreach () i identyfikatora przyrostu nie jest trudne, jeśli masz wiele elementów tej samej klasy. Dodałem to rozwiązanie jako alternatywę dla tych, którzy mogą korzystać z jQuery. I tak OP otrzymał już kilka odpowiednich odpowiedzi :-)
The Krotek