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');
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
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;
}
}
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.
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")
IE8:
document.getElementsByClassName = function (className) {
return document.querySelectorAll('.' + className)
}
function _getClass(whatEverClasNameYouWant){
var a=document.getElementsByTagName('*');
for(b in a){
if((' '+a[b].className+' ').indexOf(' '+whatEverClasNameYouWant+' ')>-1){
return a[b];
}
}
}
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
);