wake-up-neo.com

Kompatibilität von javascript document.getElementsByClassName mit IE

Was ist die beste Methode, um ein Array von Elementen mit einer bestimmten Klasse abzurufen?

Ich würde document.getElementsByClassName verwenden, aber IE unterstützt es nicht.

Also versuchte ich Jonathan Snooks Lösung :

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

... aber IE sagt immer noch:

Das Objekt unterstützt diese Eigenschaft oder Methode nicht

Irgendwelche Ideen, bessere Methoden, Fehlerbehebungen?

Ich würde es vorziehen, keine Lösungen mit jQuery oder anderem "sperrigem Javascript" zu verwenden.

Aktualisieren:

Ich habe es geschafft zu arbeiten!

Wie @ Joe erwähnt ist die Funktion keine Methode von document.

Der Arbeitscode würde also so aussehen:

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


... Auch , wenn Sie nur IE8 + -Unterstützung benötigen , funktioniert Folgendes:

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

Verwenden Sie es wie gewohnt:

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

Es ist keine Dokumentmethode:

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
55
Joe

sie können die Funktion für ältere Browser erstellen

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

Ich bin mir ziemlich sicher, dass dies die gleiche Funktion ist wie Leonids, aber dies verwendet document.getElementsByClassName wenn es geht.

13
Mike_OBrien

Sie können getElementsByClassName nicht wirklich replizieren, da es eine nodeList zurückgibt und daher den Wert live hat und mit dem Dokument aktualisiert.

Sie können ein statisches Array von Elementen zurückgeben, die dieselben Klassennamen haben, aber nicht wissen, wann sich das Dokument ändert.

(Es wird nicht zu viele solcher Dinge erfordern, um eine Bibliothek schlank aussehen zu lassen ...)

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

//Beispiel

var A = getArrayByClassNames ('sideBar local')

10
kennebec

IE8:

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

Ich möchte nur querySelectorAll Fallback für IE8 verbessern.

Wie andere geantwortet haben, ist der einfache Weg, die Funktion zu Element.prototype Mit hinzuzufügen

this.querySelectorAll('.' + className);

Es gibt jedoch einige Probleme:

  • Es funktioniert nicht mit unbeschnittenen Zeichenfolgen (am Anfang).
  • Es funktioniert nicht mit mehreren Klassen.
  • Es funktioniert nicht mit "seltsamen" Klassenzeichen (/, $, * Usw.)
  • Es funktioniert nicht mit Klassen, die mit einer Ziffer beginnen (ungültige Bezeichner)

Das bedeutet, dass es einige "Korrekturen" geben sollte, zum Beispiel:

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

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
Oriol