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的一篇文章。