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