函数三:getElementsByClassName()
我们知道,原生的JS给我们提供了getElementsByClassName方法,可以通过此方法获取到含有某指定class的节点集合,注意是集合,也就是此函数返回一个数组。
但是,IE却并不支持这个方法,但这方法却是很有实用性,所以,我们又不得不专门为IE实现这么一个函数。
怎么实现呢?我们想,这是获取某节点下含有某class的方法,那么,我们就要给这个函数传两个参数:className和context上下文。接着,我们可以判断浏览器是否支持getElementsByClassName方法,支持的话,我们直接调用此方法返回,不支持,则继续下面的思路。
1.获取所有document或者传进来的context下的所有节点元素,可以通过node.getElementsByTagName('*')实现;
2.遍历获取到的所有节点,匹配我们指定的className,成功匹配则存进一个数组保存,因为相同的class可以有多个,所以不能一匹配到就返回,要存进数组里,最后再一次性返回。
上面的思路并不是很清晰,但代码会清晰得告诉我们,如下:
function getElementsByClassName(className,context){ context = context || document; //如果有指定从某个元素里寻找,则会比每次都遍历document快得多 if(context.getElementsByClassName){ //如果浏览器支持原生的方法,则直接用原生的方法,为什么?你有把握你写的方法比原生提供的好吗? return context.getElementsByClassName(className); } var nodes = context.getElementsByTagName('*'); //遍历 var rets = []; //存放匹配到的节点 for(var i = 0; i < nodes.length; i++){ if(hasClass(className,nodes[i])){ //hasClass派上用场了 rets.push(nodes[i]); } } return rets; }
测试代码如下:
<script type="text/javascript"> function getElementsByClassName(className,context){ context = context || document; if(context.getElementsByClassName){ return context.getElementsByClassName(className); } var nodes = context.getElementsByTagName('*'); var rets = []; for(var i = 0; i < nodes.length; i++){ if(hasClass(className,nodes[i])){ rets.push(nodes[i]); } } return rets; } function hasClass(className,node){ var classNames = node.className.split(/\s+/); for(var i = 0; i < classNames.length; i++){ if(classNames[i] == className){ return true; } } return false; } window.onload = function(){ var test = document.getElementById('test'); alert(getElementsByClassName('test1',test).length); //2 } </script> </head> <body> <div id="test"> <div class="test1"></div> <div class="test1"></div> </div> </body>