document javascript.compatibilité getElementsByClassName avec IE

Quelle est la meilleure méthode pour récupérer un tableau d'éléments qui ont une certaine classe?

j'utiliserais le document.getElementsByClassName mais IE ne le supporte pas.

j'ai Donc essayé Jonathan Snook la solution :

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');

...mais IE dit toujours:

L'objet ne supporte pas cette propriété ou méthode

toutes les idées, meilleures méthodes, corrections de bugs?

je préférerais ne pas utiliser de solutions impliquant jQuery ou autre"javascript volumineux".

mise à jour:

je l'ai eu à travailler!!!

comme @joe a mentionné la fonction n'est pas une méthode de document .

ainsi le code de travail ressemblerait à ceci:

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');



...Également si vous avez seulement besoin d'IE8+ support alors ce sera le travail:

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

utilisez-le comme d'habitude:

var tabs = document.getElementsByClassName('tab');
74
demandé sur Community 2011-09-14 07:29:36

7 réponses

ce n'est pas une méthode de document:

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
répondu Joe 2011-09-14 03:32:57

vous pouvez créer la fonction pour les navigateurs plus anciens

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;
    }
}
17
répondu gdarcan 2011-12-12 10:01:42
function getElementsByClassName(className) {
if (document.getElementsByClassName) { 
  return document.getElementsByClassName(className); }
else { return document.querySelectorAll('.' + className); } }

Je suis sûr que c'est la même chose que la fonction de Leonid mais cela utilise document.getElementsByClassName quand il le peut.

13
répondu Mike_OBrien 2015-03-18 20:42:12

vous ne pouvez pas vraiment répliquer getElementsByClassName, parce qu'il renvoie un nodeList, et donc sa valeur est en direct, et mise à jour avec le document.

Vous pouvez retourner un Tableau statique d'éléments qui partagent les mêmes noms de classe- mais il ne saura pas quand le document changera.

(Il ne prendra pas trop de ce genre de choses pour faire une bibliothèque look svelte...)

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

/ / exemple

var a = getarrayyclassnames ("sideBar local")

9
répondu kennebec 2013-07-31 02:53:20

IE8:

document.getElementsByClassName = function (className) {
    return document.querySelectorAll('.' + className)
}
8
répondu Leonid 2011-09-14 04:08:46
function _getClass(whatEverClasNameYouWant){
var a=document.getElementsByTagName('*');
   for(b in a){
      if((' '+a[b].className+' ').indexOf(' '+whatEverClasNameYouWant+' ')>-1){
      return a[b];
      }
   }
}
0
répondu Mohd Afique 2012-02-02 05:38:59

je veux juste améliorer querySelectorAll de secours pour IE8.

comme d'autres ont répondu, la manière simple est d'ajouter la fonction à Element.prototype avec

this.querySelectorAll('.' + className);

mais il y a quelques problèmes:

  • il ne fonctionne pas avec des cordes non tronquées (au début).
  • ça ne marche pas avec plusieurs classes.
  • ça ne marche pas avec les caractères de classe" étranges" ( / , $ , * , etc.)
  • il ne fonctionne pas avec les classes qui commencent par un chiffre (identificateurs invalides)

cela signifie Qu'il devrait y avoir une "fixation", par exemple:

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

Code:

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
répondu Oriol 2014-02-09 14:12:20