javascript document.getElementsByClassName compatibilidade com o IE

Qual é o melhor método para recuperar uma matriz de elementos que possuem uma determinada class?

Eu usaria document.getElementsByClassName, mas o IE não suporta isso.

Então eu tentei a solução 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'); 

… mas o IE ainda diz:

Objeto não suporta esta propriedade ou método

Alguma idéia, melhores methods, correções de bugs?

Eu preferiria não usar nenhuma solução envolvendo jQuery ou outro “javascript volumoso”.

Atualizar:

Eu tenho que trabalhar!

Como @joe mencionou, a function não é um método de document .

Então o código de trabalho ficaria assim:

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

… Além disso, se você precisar apenas do suporte ao IE8 + , isso funcionará:

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

Use como se fosse normal:

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

Não é um 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 

você pode criar a function para navegadores mais antigos

 if (typeof document.getElementsByClassName!='function') { document.getElementsByClassName = function() { var elms = document.getElementsByTagName('*'); var ei = new Array(); for (i=0;i 
 function getElementsByClassName(className) { if (document.getElementsByClassName) { return document.getElementsByClassName(className); } else { return document.querySelectorAll('.' + className); } } 

Tenho certeza que isso é o mesmo que a function de Leonid, mas isso usa document.getElementsByClassName quando pode.

Você não pode realmente replicar getElementsByClassName, porque ele retorna um nodeList e, portanto, seu valor é ao vivo e atualiza com o documento.

Você pode retornar uma matriz estática de elementos que compartilham os mesmos nomes de class, mas não “saberá” quando o documento for alterado.

(Não vai demorar muito deste tipo de coisas para fazer uma biblioteca parecer esbelta …)

 function getArrayByClassNames(classs, pa){ if(!pa) pa= document; var C= [], G; if(pa.getElementsByClassName){ G= pa.getElementsByClassName(classs); for(var i= 0, L= G.length; i 

//Exemplo

var A = getArrayByClassNames ('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]; } } } 

Eu só quero melhorar querySelectorAll fallback para o IE8.

Como os outros responderam, a maneira mais simples é adicionar a function ao Element.prototype com

 this.querySelectorAll('.' + className); 

Mas existem alguns problemas:

  • Não funciona com strings não aparadas (no começo).
  • Não funciona com várias classs.
  • Não funciona com caracteres de class “estranhos” ( / , $ , * , etc.)
  • Não funciona com classs que começam com um dígito (identificadores inválidos)

Isso significa que deveria haver algum “conserto”, por exemplo:

 "abcd" -> ".abcd" "ab cd" -> ".abcd" " ab " -> ".ab " "a/b$cd" -> ".a\/b\$cd" "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 classs, removing spaces );