¿Cómo obtener elemento por clase en JavaScript?

226

Quiero reemplazar el contenido dentro de un elemento html, así que estoy usando la siguiente función para eso:

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

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

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

Lo anterior funciona muy bien, pero el problema es que tengo más de un elemento html en una página en la que quiero reemplazar el contenido. Así que no puedo usar identificadores sino clases en su lugar. Me han dicho que JavaScript no admite ningún tipo de elemento incorporado incorporado por función de clase. Entonces, ¿cómo se puede revisar el código anterior para que funcione con clases en lugar de identificadores?

PD: No quiero usar jQuery para esto.

Taylor
fuente

Respuestas:

198

Este código debería funcionar en todos los navegadores.

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

La forma en que funciona es recorriendo todos los elementos del documento y buscando en su lista de clases matchClass. Si se encuentra una coincidencia, el contenido se reemplaza.

Ejemplo de jsFiddle, utilizando Vanilla JS (es decir, sin marco)

Randy the Dev
fuente
55
+1 - Buena captura con los espacios, siempre me olvido de hacer eso ... voy a robar eso para mi respuesta;) aunque la clase es una palabra reservada en javascript; no debe usarlo para un nombre de variable a pesar de que realmente no hace ningún daño (todavía).
Dagg Nabbit
1
@no con esa función no tiene que tener ningún contenido dentro del elemento que desea reemplazar. Puede tener una cadena allí o puede tenerla vacía. De cualquier manera, el texto de reemplazo aparecerá repentinamente allí cuando se llame a la función.
Taylor
44
Andrew, @no: el uso classcomo nombre de variable no funciona en Safari, por lo que actualmente tiene un impacto.
user113716
44
La matriz devuelta por getElementsBytagName también tiene una propiedad de longitud, para la cual también se realiza la prueba className / indexOf. Aunque esto no es un problema en este caso, un ciclo for regular sería más correcto.
Wolfgang Stengel
1
en lugar de indexOf con espacios, guardar elems[i].className, decir var cny usar cn && cn.match(new RegExp("(^|\\s)" + matchClass + "(\\s|$)"))funcionaría mejor porque coincide con cualquier espacio en blanco (espacio, espacio sin separaciones, tabulación, etc.) y al mismo tiempo permite que coincidan los nombres de primera / última clase. Ejemplo: jsfiddle.net/AXdtH/1636
Supuhstar
178

Por supuesto, todos los navegadores modernos ahora admiten la siguiente manera más simple:

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

pero ten en cuenta que no funciona con IE8 o antes. Ver http://caniuse.com/getelementsbyclassname

Además, no todos los navegadores devolverán un estado puro NodeListcomo deberían.

Probablemente todavía estés mejor usando tu biblioteca favorita de navegador cruzado.

Frio frio
fuente
Para IE8 puede usar querySelectorAll.
Gras Double
109
document.querySelectorAll(".your_class_name_here");

Eso funcionará en navegadores "modernos" que implementen ese método (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");

Si desea proporcionar soporte para navegadores más antiguos, puede cargar un motor de selección independiente como Sizzle (4KB mini + gzip) o Peppy (10K mini) y recurrir a él si no se encuentra el método querySelector nativo.

¿Es excesivo cargar un motor selector solo para poder obtener elementos con una clase determinada? Probablemente. Sin embargo, los scripts no son tan grandes y es posible que el motor de selección sea útil en muchos otros lugares de su script.

Cristian Sanchez
fuente
@Taylor: Creo que funciona en IE8 (no estoy 100% seguro, es demasiado vago para googlearlo). En cualquier caso, agregué información sobre la compatibilidad con versiones anteriores utilizando motores de selección de terceros.
Cristian Sanchez
18
document.querySelectorfunciona en IE8 y superior: caniuse.com/queryselector
Zeke
26

Una manera simple y fácil

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
fuente
6

Me sorprende que no haya respuestas usando Expresiones regulares. Esta es la respuesta de Andrew , en RegExp.testlugar de usar String.indexOf, ya que parece funcionar mejor para múltiples operaciones, de acuerdo con las pruebas de jsPerf .
También parece ser compatible con 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.");

Si busca las mismas clases con frecuencia, puede mejorarlas almacenando las expresiones regulares (precompiladas) en otro lugar y pasándolas directamente a la función, en lugar de una cadena.

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
fuente
4

Esto debería funcionar en casi cualquier navegador ...

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

Deberías poder usarlo así:

function replaceInClass (className, content) {
  var nodes = getByClass(className), i=-1, node;
  while (node=nodes[++i]) node.innerHTML = content;
}
Dagg Nabbit
fuente
3

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

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

Roger Causto
fuente
44
Esa no es realmente una respuesta. Intenta explicar tu código . Además, es básicamente una versión más compacta de otra respuesta a esta pregunta que se publicó hace 5 años.
Helmbert
No sé cuál es el problema. Esta respuesta esta bien. No hay comentario ... y qué? Esta no es la regla de oro. ¿Y qué quieres comentar aquí? Y ¿ Pero es un código legible?
AntiCZ
3

Supongo que esta no era una opción válida cuando se le preguntó originalmente, pero ahora puede usarla document.getElementsByClassName('');. Por ejemplo:

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

Consulte la documentación de MDN para más información.

Thornjad
fuente
0

Pienso algo como:

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

trabajaría

KeatsKelleher
fuente
1
si solo tiene un puñado de elementos en su página, de lo contrario, esta es la solución O (N)
jwl
getAttribute ('class') parece funcionar en todos menos IE, luego getAttribute ('className') funciona en IE
KeatsKelleher
0

jQuery maneja esto fácilmente.

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

Cambia todos los elementos .myclass a ese texto.

Daniel Høifødt
fuente
PD: la pregunta dice ". No quiero usar jQuery para esto".
Julián
Ok, no vi eso.
Daniel Høifødt
-15

Cuando algunos elementos carecen de ID, uso jQuery así:

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

Esta podría ser una solución extraña, pero tal vez alguien lo encuentre útil.

El krotek
fuente
3
Si hay varios elementos con clase myclass, todos obtendrán la identificación myid, ¡pero los identificadores deben ser únicos! Además, OP dice explícitamente que evite jQuery.
Oriol
1
No es difícil agregar una cláusula foreach () e ID de incremento, si tiene varios elementos de la misma clase. Agregué esta solución como una alternativa para aquellos que pueden usar jQuery. OP ya recibió un montón de respuestas adecuadas de todos modos :-)
The Krotek