all know: 除IE8及如下版本,getElementsByClassName方法在全部浏览器中都实现了。javascript
本文来分析总结下不一样框架或库中,getElementsByClassName的兼容IE8-的实现方法。html
框架:NEJjava
库: jQuerynode
1、NEJ框架的实现方法正则表达式
__getElementsByClassName = function(_element,_class){ var _result = [], _regexp = new RegExp('(\\s|^)(?:'+_class.replace(/\s+/g,'|')+')(?=\\s|$)'); _u._$forEach( _element.getElementsByTagName('*'), function(_node){ if (_regexp.test(_node.className)){ _result.push(_node); } } ); return _result; };
以上代码不能够直接使用,对nej框架中的其余API有依赖。数组
但其设计原理是很清晰的:浏览器
一、新建 匹配类名的 正则表达式 ;ruby
二、用HTMLElement元素的getElementByTagName方法选出该元素包含的全部子元素;框架
三、对选出的每一个子元素 用正则表达式判断,看子元素类名中是否包含指定类名;若是包含,则把它推到result数组。spa
2、在网友 Ruby’s Louvre 的一篇总结的基础上稍加改进,并调试经过 获得的一种方法:
注:该段代码能够直接使用,不依赖任何框架或库!
/* 第一个参数是必须的,后两个参数是可选的,兼容IE6/7/8 */ var getElementsByClassName = function (searchClass, node,tag) { if(document.getElementsByClassName){ var nodes = (node || document).getElementsByClassName(searchClass),result = []; for(var i=0 ;node = nodes[i++];){ if(!!tag){ if(tag !== "*" && node.tagName === tag.toUpperCase()){ result.push(node); } }else{ result.push(node); } } return result; }else{ node = node || document; tag = tag || "*"; var result = []; var classes = searchClass.split(" "), elements = (tag === "*" && node.all)? node.all : node.getElementsByTagName(tag), patterns = [], current, match; var i = classes.length; while(--i >= 0){ patterns.push(new RegExp("(^|\\s)" + classes[i] + "(\\s|$)")); } var j = elements.length; while(--j >= 0){ current = elements[j]; match = false; for(var k=0,n=0, kl=patterns.length; k<kl; k++){ match = patterns[k].test(current.className); if (match) n++; } if(n == kl){ result.push(current); } } return result; } } getElementsByClassName("filament_table red cell") ; getElementsByClassName("filament_table red cell",document,"div") ;
3、jQuery库 中 类选择器的实现,是集成在sizzle选择器引擎中的,其中用到了大量的正则表达式。
具体可参考Aaron的一篇文章。