Pregunta javascript document.getElementsByClassName compatibilidad con IE


¿Cuál es el mejor método para recuperar una matriz de elementos que tienen una determinada clase?

Yo usaría document.getElementsByClassName pero IE no lo admite.

Así que lo intenté La solución de Jonathan Snook:

function getElementsByClassName(node, classname) {
    var a = [];
    var re = new RegExp('(^| )'+classname+'( |$)');
    var els = node.getElementsByTagName("*");
    for(var i=0,j=els.length; i<j; i++)
        if(re.test(els[i].className))a.push(els[i]);
    return a;
}
var tabs = document.getElementsByClassName(document.body,'tab');

... pero IE todavía dice:

El objeto no admite esta propiedad o método

¿Alguna idea, mejores métodos, correcciones de errores?

Preferiría no utilizar ninguna solución que involucre jQuery u otro "javascript voluminoso".

Actualizar:

¡Yo tengo que trabajar!

Como @joe mencionado la función no es un método de document.

Entonces el código de trabajo sería así:

function getElementsByClassName(node, classname) {
    var a = [];
    var re = new RegExp('(^| )'+classname+'( |$)');
    var els = node.getElementsByTagName("*");
    for(var i=0,j=els.length; i<j; i++)
        if(re.test(els[i].className))a.push(els[i]);
    return a;
}
var tabs = getElementsByClassName(document.body,'tab');


...También si solo necesitas soporte IE8 + entonces esto funcionará:

if(!document.getElementsByClassName) {
    document.getElementsByClassName = function(className) {
        return this.querySelectorAll("." + className);
    };
    Element.prototype.getElementsByClassName = document.getElementsByClassName;
}

Úselo como siempre:

var tabs = document.getElementsByClassName('tab');

74
2017-09-14 03:29


origen


Respuestas:


No es un método de documento:

function getElementsByClassName(node, classname) {
    var a = [];
    var re = new RegExp('(^| )'+classname+'( |$)');
    var els = node.getElementsByTagName("*");
    for(var i=0,j=els.length; i<j; i++)
        if(re.test(els[i].className))a.push(els[i]);
    return a;
}

tabs = getElementsByClassName(document.body,'tab');  // no document

54
2017-09-14 03:32



puedes crear la función para navegadores más antiguos

if (typeof document.getElementsByClassName!='function') {
    document.getElementsByClassName = function() {
        var elms = document.getElementsByTagName('*');
        var ei = new Array();
        for (i=0;i<elms.length;i++) {
            if (elms[i].getAttribute('class')) {
                ecl = elms[i].getAttribute('class').split(' ');
                for (j=0;j<ecl.length;j++) {
                    if (ecl[j].toLowerCase() == arguments[0].toLowerCase()) {
                        ei.push(elms[i]);
                    }
                }
            } else if (elms[i].className) {
                ecl = elms[i].className.split(' ');
                for (j=0;j<ecl.length;j++) {
                    if (ecl[j].toLowerCase() == arguments[0].toLowerCase()) {
                        ei.push(elms[i]);
                    }
                }
            }
        }
        return ei;
    }
}

16
2017-12-12 10:01



function getElementsByClassName(className) {
if (document.getElementsByClassName) { 
  return document.getElementsByClassName(className); }
else { return document.querySelectorAll('.' + className); } }

Bastante seguro de que esto es lo mismo que la función de Leonid, pero esto se usa document.getElementsByClassName cuando puede.


13
2017-10-31 15:52



Realmente no se puede replicar getElementsByClassName, porque devuelve un nodeList, y entonces su valor es en vivo y se actualiza con el documento.

Puede devolver una matriz estática de elementos que comparten los mismos nombres de clase- pero no 'sabrá' cuando cambie el documento.

(No tomará muchas de estas cosas para hacer que una biblioteca se vea esbelta ...)

function getArrayByClassNames(classes, pa){
    if(!pa) pa= document;
    var C= [], G;
    if(pa.getElementsByClassName){
        G= pa.getElementsByClassName(classes);
        for(var i= 0, L= G.length; i<L; i++){
            C[i]= G[i];
        }
    }
    else{
        classes= classes.split(/\s+/);
        var who, cL= classes.length,
        cn, G= pa.getElementsByTagName('*'), L= G.length;
        for(var i= 0; i<cL; i++){
            classes[i]= RegExp('\\b'+classes[i]+'\\b');
        }
        classnameLoop:
        while(L){
            who= G[--L];
            cn= who.className;
            if(cn){
                for(var i= 0; i<cL; i++){
                    if(classes[i].test(cn)== false) {
                        continue classnameLoop;
                    }
                }
                C.push(who);
            }
        }
    }
    return C;
}

//Ejemplo

var A = getArrayByClassNames ('sideBar local')


9
2017-09-14 04:20



IE8:

document.getElementsByClassName = function (className) {
    return document.querySelectorAll('.' + className)
}

8
2017-09-14 04:08



function _getClass(whatEverClasNameYouWant){
var a=document.getElementsByTagName('*');
   for(b in a){
      if((' '+a[b].className+' ').indexOf(' '+whatEverClasNameYouWant+' ')>-1){
      return a[b];
      }
   }
}

0
2018-02-02 05:21



Solo quiero mejorar querySelectorAll alternativa para IE8.

Al igual que otros respondieron, la forma simple es agregar la función a Element.prototype con

this.querySelectorAll('.' + className);

Pero hay algunos problemas:

  • No funciona con cadenas sin recortar (al principio).
  • No funciona con múltiples clases.
  • No funciona con caracteres de clase "extraños" (/, $, *, etc.)
  • No funciona con clases que comienzan con un dígito (identificadores no válidos)

Eso significa que debe haber algo de "fijación", por ejemplo:

"abcd"     ->  ".abcd"
"a   b cd" ->  ".a.b.cd"
"   a b  " ->  ".a.b  "
"a/b$c d"  ->  ".a\/b\$c.d"
"1234"     ->  ".\000031234"

Código:

this.querySelectorAll(className
    .replace(/(?=[^ \w])/g, '\\')   // Escape non-word characters
    .replace(/\b\d/g, '\\00003$&')  // Escape digits at the beginning
    .replace(/(^| +)(?!$| )/g, '.') // Add "." before classes, removing spaces
);

0
2018-02-09 02:25