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

由于原生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时,果然发现了相同的元素

164032_Wtfw_2357982.png

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

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中的相同的元素就没有了!!!

没有了!!!

没有了!!!

没有了!!!

164246_1FpP_2357982.png

这是为什么?

继续试验

给每个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 

感谢淼哥

 

转载于:https://my.oschina.net/dennis1991/blog/813054

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值