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

因为原生js中,没有能经过class获取元素的方法,OK,来,本身写javascript

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;
}

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

页面结构是这样的java

<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解决了,返回的数组中有四个元素,就是我须要的那四个元素。dom

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

 

 

正当我觉得事情解决的时候,忽然想到一个问题,为何,对于for in遍历,返回的数组中会有两个相同的元素?难道children中自己就有两个同样的元素?htm

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

果真,有相同的元素,并且,诡异的是get

length竟然仍是5!!!io

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 

感谢淼哥

相关文章
相关标签/搜索