先看一下问题:
1 window.onload=function(){
2 createDom();
3 operateDom();
4 //code stuff
5 }
其中 createDom()通过异步请求取得大量数据,然后组织起
来;operateDom()是通过遍历操作createDom生成的节点。问题出现了:页面显示的并不是我们想要的效果。为什么?operateDom
并不能总是取到生成的dom节点。由于生成的dom节点附加到页面dom树的时候存在着延迟,所以在createDom里面数据量比较大、生成dom节点
比较多的时候,这种时间差会很大(对机器而言)。虽然createDom里面的语句执行完毕,接下来执行operateDom,但那些生成的节点也许还没
有完全附加到dom树上面,所以就存在取不到dom节点的情况。
也许你会想,为什么不直接在createDom里面在生成那些dom的时候直接操作,而是重新进行遍历操作?问题在于createDom和
operateDom并不是同一个开发人员写的,也有可能是调用公用的东西,所以更不可能去改createDom了。这里只是为了举例方便。
怎么办?setTimeout?setTimeInterval?
setTimeout自然不可取,我们并不知道时间差是多少,设的太长了,用户体验不好,设的太短了,达不到我们的目的。
setTimeInterval可以,但这会频繁的执行,我们只需要它执行一次。针对setTimeInteval,折中的解决办法是设置哨位监视。改动
一下:
1 operateDom(){
2 if(operateDom.called)
3 return;
4 // code stuff
5 }
对Mozilla系列的浏览器(如ff/googlechrome),可以:
1 // for Mozilla browsers
2 if (document.addEventListener) {
3 document.addEventListener("DOMContentLoaded", init, false);
4 }
IE支持条件编译(js是解释执行的,这里找不到合适的词来表述,看下面的代码就知道了)。在IE系列的浏览器中,可以:
Code
Code
2 // quit if this function has already been called
3 if (arguments.callee.done) return;
4
5 // flag this function so we don't do the same thing twice
6 arguments.callee.done = true;
7
8 createDom();
9 setTimeInterval("operateDom()",100);
10 // do stuff
11 };