javascript document.getElementsByClassName与IE的兼容性

检索具有某个类的元素数组的最佳方法是什么?

我会使用document.getElementsByClassName但IE不支持它。

所以我尝试了Jonathan Snook的解决scheme :

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

…但IE仍然说:

对象不支持这个属性或方法

任何想法,更好的方法,错误修复?

我不希望使用任何涉及jQuery或其他“笨重的JavaScript”的解决scheme。

更新:

我得到它的工作!

正如@joe所提到的,这个函数不是一个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; } var tabs = getElementsByClassName(document.body,'tab'); 

…另外, 如果你只需要IE8 +支持,那么这将工作:

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

像正常一样使用它:

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

这不是一个文件的方法:

 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 

您可以创build旧版浏览器的function

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

很确定这和Leonid的函数是一样的,但是它可以使用document.getElementsByClassName

您不能真正复制getElementsByClassName,因为它返回一个nodeList,所以它的值是实时的,并且随文档一起更新。

您可以返回共享相同类名的静态数组元素 – 但文档更改时不会“知道”。

(这样做不会太多这样的事情,使图书馆看起来苗条…)

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

//例

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

我只是想改善IE8的querySelectorAll后备。

像其他人一样,简单的方法是将函数添加到Element.prototype

 this.querySelectorAll('.' + className); 

但是有一些问题:

  • 它不适用于未修剪的string(在开始处)。
  • 它不适用于多个类。
  • 它不适用于“奇怪的”类字符( /$*等)
  • 它不适用于以数字开头的类(无效标识符)

这意味着应该有一些“修复”,例如:

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

码:

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