您的位置:首页 > 其它

for in 和 for,以及getElementsByTagName('*')

2016-12-27 17:03 309 查看
由于原生js中,没有能通过class获取元素的方法,OK,来,自己写

function getElementByClassName(clsName, parent) {
var children = (parent || document.body).getElementsByTagName('*');
var result = [];
for(var i in children) {
var classes = children[i].className;
if(classes && classes.indexOf(clsName) > -1) {
result.push(children[i])
}
}
return result;
}

正在我沾沾自喜的时候,尼玛,出幺蛾子了

页面结构是这样的

<div id="wrap">
<div id="block1" class="block"></div>
<div id="block2" class="block"></div>
<div id="block3" class="block"></div>
<div id="block4" class="block"></div>
</div>

我了个擦,返回了一个8个元素的数组,有木有,好难过,这不是我想要的结果。擦干眼泪,找出问题的地方吧。看下控制台,发现这个8元素数组,该有的四个元素每个都重复了一下。我了个擦擦擦,这是为什么。在找到问题之前,我决定,先换成for循环,毕竟要先把任务完成不是。

function getElementByClassName(clsName, parent) {
var children = (parent || document.body).getElementsByTagName('*');
var result = [];
for (var i = 0; i < children.length; i++) {
var classes = children[i].className;
if (classes && classes.indexOf(clsName) > -1) {
result.push(children[i])
}
}
return result;
}

bug解决了,返回的数组中有四个元素,就是我需要的那四个元素。

我擦,这是为什么,果断求助淼哥。从淼哥那里,我得到一个重要的信息,getElementsByTagName('*')返回的不是数组,而是一个类数组,虽然有length属性,但是,并不是真正的数组。OK,事到如今,真想大白。由于getElementsByTagName,这玩意,返回的不是一个真正的数组,所以,在用for in遍历的时候,会遍历所有的key-value,而用for遍历的时候,就不会这样,只去遍历children[0],children[1],children[2]...children[length-1]

正当我以为事情解决的时候,突然想到一个问题,为什么,对于for in遍历,返回的数组中会有两个相同的元素?难道children中本身就有两个一样的元素?

果不其然,当我在控制台打印children时,果然发现了相同的元素



果然,有相同的元素,而且,诡异的是

length居然还是5!!!

length居然还是5!!!

length居然还是5!!!

接着试验,当我把div的id去掉之后

<div id="wrap">
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
</div>

children中的相同的元素就没有了!!!

没有了!!!

没有了!!!

没有了!!!



这是为什么?

继续试验

给每个div加name属性

如果几个div的name一样的话,只有第一个div会重复一次,其他的div不会重复

如果div的name都不一样,每一个元素会重复一次

id和name都存在的情况下,如果name都不一样,每个元素会重复两次!

id和name都存在的情况下,如果name都不一样,每个元素会重复两次!

id和name都存在的情况下,如果name都不一样,每个元素会重复两次!

除了id和name,其他的属性,都不会造成重复现象。

这不禁让我想起了,js的原生获取dom的三个方法,getElementById,getElementsByTagName,getElementsByName。

我猜测是,getElementsByTagName这个方法,当参数为 * 时,又去调用了另外两个方法,这个纯属猜测,目前我在谷歌和百度都还没搜到答案。等搜索到答案后,再来这里更新,也希望某位大神,能不吝赐教。

总之先牢记这个坑,用getElementsByTagName('*')获取出来的元素,遍历的时候,不要用for

感谢淼哥
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  for in for byTagName