javascript document.getElementsByClassName compatibilidad con IE

Resuelto Web_Designer asked hace 13 años • 7 respuestas

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

Usaría document.getElementsByClassName pero IE no lo admite.

Entonces probé 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, corrección de errores?

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

Actualizar:

¡Yo tengo que trabajar!

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

Entonces el código de trabajo se verí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');


...Además , si solo necesitas soporte para IE8+, esto funcionará:

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

Úselo como de costumbre:

var tabs = document.getElementsByClassName('tab');
Web_Designer avatar Sep 14 '11 10:09 Web_Designer
Aceptado

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
Joe avatar Sep 14 '2011 03:09 Joe

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;
    }
}
gdarcan avatar Dec 12 '2011 10:12 gdarcan
function getElementsByClassName(className) {
if (document.getElementsByClassName) { 
  return document.getElementsByClassName(className); }
else { return document.querySelectorAll('.' + className); } }

Estoy bastante seguro de que esta es la misma función de Leonid, pero se usa document.getElementsByClassNamecuando puede.

Mike_OBrien avatar Oct 31 '2011 15:10 Mike_OBrien

Realmente no se puede replicar getElementsByClassName, porque devuelve una lista de nodos, por lo que su valor está activo y se actualiza con el documento.

Puede devolver una matriz estática de elementos que comparten los mismos nombres de clase, pero no "sabrá" cuándo cambia el documento.

(No se necesitan muchas cosas de este tipo para que una biblioteca luzca 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('barra lateral local')

kennebec avatar Sep 14 '2011 04:09 kennebec

IE8:

document.getElementsByClassName = function (className) {
    return document.querySelectorAll('.' + className)
}
Leonid avatar Sep 14 '2011 04:09 Leonid