玩死浏览器的n种方法 (1)—-动态dom集合导致的无限循环

来看看这段简单的dom操作,clone子节点操作代码:将div内的子节点挨个clone一次,然后再插入这个div内

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<body>
<a href="javascript:void(0);" id="start">start</a>
<div id="test">
  <div>t1</div>
  <div>t2</div>
</div>
<script type="text/javascript">
window.onload = function(){
  document.getElementById('start').onclick = function(){
	var div = document.getElementById('test'),
	  childs = div.getElementsByTagName('div');
	for(var i = 0; i < childs.length; i++){
	  var d = childs[i].cloneNode(true);
	  div.appendChild(d);
	}
  };
};
</script>
</body>

试着执行一下,你会发现,浏览器卡死了 :(
为什么哪?
因为通过getElementsByTagName取得的节点集合childs是动态的,当继续往父节点div内添加子节点时,也同时将这些节点添加到了childs的里面~~所以循环变成了无限的
对于这个例子,你可以在循环前将将childs.length保存到一个变量里面,然后在循环时,将i与这个变量比较
当然,这样并非真的解决了问题,比如你如果是要通过insertBefore插入节点,即插入的节点不是在已有的节点后面,上面虽然不会死循环,但循环仍然会乱掉,原因很简单:childs是动态的
正切的做法是重新定义一个childs数组,让后将原来的DOM对象childs里的节点,放到js数组childs里面,这时的childs就不再是动态的了

3 Comments

  • 2013 年 01 月 18 日 - 上午 11:05 | Permalink

    多学 多看 多问

  • 2013 年 01 月 30 日 - 上午 8:14 | Permalink

    哥 你写的博客怎么着也得让后世的研究者们折腾上半个世纪。

    • admin
      2013 年 01 月 30 日 - 下午 10:55 | Permalink

      嘛意思?

  • 企业名录 进行回复 取消回复

    电子邮件地址不会被公开。 必填项已用 * 标注

    *

    *