浏览器加载的顺序
1.HTML解析完毕
2.外部脚本和样式加载完毕
3.脚本在文档内解析并执行
4.HTML DOM完全构造起来
5.图片个外部内容加载
6.网页完全加载
1-4执行是很快的,5很慢
因为document.getElementById这些只需要1-4加载完毕就可以执行,并不需要加载第五条,所以我们需要一种可以代替window.onload的更加快捷的加载方案。
非ie提供一中加载事件DOMContentLoaded事件,这个事件可以在完成HTML DOM结构之后就会触发,不会理会图像音乐,js文件,css文件或其他资源是否已经下载完毕
支持度 IE9+、Firefox、chrome、safari 3.1+、opera 9+
window.onload是页面加载完毕,包括图片等
所以我们要做到在图片等资源加载前完成DOM操作等
在w3c中 有DOMContentLoaded事件,表示HTML DOM是否加载完毕(不用等到第五步就可以执行)
addEvent(document,'DOMContentLoaded',function(){ var box=document.getElementById('box') })
但是IE678没有这个事件,所以要用IE678模拟DOMContentLoaded方法
方法1:
document.write("<script id='ie' defer='defer' src='javascript:void(0)'></script>"); var ie=document.getElementById('ie');
先创建一个script标签,并设置为defer,defer作用是文档加载完毕了再执行脚本,然后查找到这个标签利用onreadystatechange事件和readyState属性判断加载状态,如果this.readyState == 'complete'表示页面DOM加载完毕
ie.onreadystatechange=function(){ if(this.readyState == 'complete'){ var box=document.getElementById('box'); alert(box.innerHTML) } }
缺陷 如果页面中有iframe标签,那么会等到iframe执行完
this.readyState 的状态才变为'complete'
所以了方法2:
ie有个特有的doScroll方法,当页面DOM未加载完成时,调用doScroll方法时,就会报错,反过来,只要一直间隔调用doScroll直到不报错,那就表示页面DOM加载完毕了。
那么就可以通过doScroll方法来完成模拟
var timer=null; timer=setInterval(function(){ try{ document.documentElement.doScroll('left'); var box=document.getElementById('box'); alert(box.innerHTML) }catch(e){} })
这里也可以用setTimeOut
function doScroll(){ try{ document.documentElement.doScroll('left'); } catch(error){ return setTimeout(doScroll,20); }; execFn(); };
这样就模拟成功了 不会出现刚才的问题了
兼容:
function addDomloaded(fn){ if(document.addEventListener){ //w3c addEvent(document,'DOMContentLoaded',function(){ fn(); }) }else{ //ie var timer=null; timer=setInterval(function(){ try{ document.documentElement.doScroll('left'); fn(); }catch(e){} }) } }
但是用完就要删除这个事件
//用完就删除这个事件
removeEvent(document,'DOMContentLoaded',arguments.callee)
function addDomloaded(fn){ if(document.addEventListener){ //w3c addEvent(document,'DOMContentLoaded',function(){ fn(); //用完就删除这个事件 removeEvent(document,'DOMContentLoaded',arguments.callee) }) }else{ //ie var timer=null; timer=setInterval(function(){ try{ document.documentElement.doScroll('left'); fn(); }catch(e){} }) } }
对于一些非主流的浏览器 怎么办呢?
首先我们要了解
HTML DOM readyState 属性
该属性返回以下值:
- uninitialized - 还未开始载入
- loading - 载入中
- interactive - 已加载,文档与用户可以开始交互
- complete - 载入完成
所以我们可以判断文档是否加载到interactive这个环节,
document.onreadystatechange=function(){ if(/interactive/.test(document.readyState)){ var box=document.getElementById('box'); alert(box.innerHTML); } }
这样就可以在图片等资源加载前操作DOM,而且 主流浏览器也支持这种方法(IE678也支持哦)