通常来说,window.onload就够用了,如果想加载多个事件,我们可以采取以下方式:

window.onload = function(){

       func1();
       func2();
       func3();
       //更多加载事件………………

}

但是如果我们需要页面完全呈现前做一些东西呢,如通过脚本加载其他js文件,或在IE6实现fixed……这些东西就要用到domReady 了,domReady好像是jQuery的叫做,一个加载函数。在W3C的草稿中,它其中是一种事件,名为 DOMContentLoaded。DOMContentLoaded事件比onload事件快许多,它是在DOM树建成之时就触发,而onload必须 要等待页面所有元素的资源都下载完毕时才触发。在标准游览器中调用这个事件很简单的:

document.addEventListener('DOMContentLoaded', function(){
   alert("DOM树建成了!")
 }, false);

IE虽然有这么多私有事件,但却没有一个与它相同的,最接近的是readystatechange,加上其他乱七八糟的东西,我们还是能够模拟DOMContentLoaded的。

有时我们加载事件时,可能不是单是通过一个函数就加载完的。比如我要用window.onload加载一段代码,但我还通过JS文件加载一个开源插 件,那个插件当它要处理DOM,还是需要等到DOM树完成之时,因此它可能也要搞一个window.onload块。这时页面拥有两个 window.onload代码块,很显然,第二个会覆盖掉第一个。这时,我们就要用到loadEvent这样的多重加载函数了。

var loadEvent = function(fn) {
    var oldonload = window.onload;
    if (typeof window.onload != 'function') {
        window.onload = fn;
    }else {
        window.onload = function() {
            oldonload();
            fn();
        }
    }
}
//*******************用法*******************
loadEvent(handler1);
loadEvent(handler2);
loadEvent(handler3);

在标准游览器中,因为有addEventListener,很轻松就实现DOMContentLoaded的多重加载,那IE怎么办?唯一的办法 是,无论是addEventListener还是attachEvent都执行,把多个要加载的代码整合到一块,一次性执行。因此,我们需要一个数组。

window.DOMLoadEvents = [];
 
var addDOMLoadEvent = function(handler) {
    window.DOMLoadEvents[window.DOMLoadEvents.length]=handler
}
 
addDOMLoadEvent(handler);
addDOMLoadEvent(handler);
addDOMLoadEvent(handler);
//更多加载事件

那么怎样执行它们,上面仅仅是添加事件,我们需要另一个函数,专门用来执行它的。

var fireContentLoadedEvent = function() {
    if (arguments.callee.loaded) return;
    //让此函数仅仅执行一次
    arguments.callee.loaded = true;
    var handlers = window.DOMLoadEvents,length = handlers.length;
    for (var i=0; i<length; i++) {
        var func = handlers[i];
        func();//执行要在domReady运行的代码
    }
}

那么我们要在什么时候执行上面的函数呢?我们仅讨论IE的情况。在IE中,任何DOM元素都有一个doScroll 方法,无论它们是否支持滚动条。为了判断DOM树是否建成,我们只看看documentElement是否完整就是,因为,它作为最外层的元素,作为 DOM树的根部而存在,如果documentElement完整的话,就可以调用doScroll方法了。当页面一加载JS时,我们就执行此方法,当然要 如果documentElement还不完整就会报错,我们在catch块中重新调用它,一直到成功执行,成功执行时就可以调用 fireContentLoadedEvent 方法了。

参数 描述
scrollbarDown Default. Down scroll arrow is at the specified location
scrollbarHThumb Horizontal scroll thumb or box is at the specified location
scrollbarLeft Left scroll arrow is at the specified location
scrollbarPageDown Page-down scroll bar shaft is at the specified location
scrollbarPageLeft Page-left scroll bar shaft is at the specified location
scrollbarPageRight Page-right scroll bar shaft is at the specified location
scrollbarPageUp Page-up scroll bar shaft is at the specified location
scrollbarRight Right scroll arrow is at the specified location
scrollbarUp Up scroll arrow is at the specified location
scrollbarVThumb Vertical scroll thumb or box is at the specified location
down Composite reference to scrollbarDown
left Composite reference to scrollbarLeft
pageDown Composite reference to scrollbarPageDown.
pageLeft Composite reference to scrollbarPageLeft.
pageRight Composite reference to scrollbarPageRight.
pageUp Composite reference to scrollbarPageUp.
right Composite reference to scrollbarRight.
up Composite reference to scrollbarUp.
var  pollDoScroll = function() {
    try {
        document.documentElement.doScroll('left');
    }catch(e) {
        setTimeout(arguments.callee, 10);
        return;
    }
    fireContentLoadedEvent();
}

我们要页面加载JS立即执行此函数,是直接pollDoScroll()吗?!不要忘记,它只是应用于IE中,我们还要判定一下浏览器。如果支持 addEventListener,也肯定支持DOMContentLoaded了(不考虑旧版本),否则就运行pollDoScroll函数。

if (document.addEventListener) {
    document.addEventListener('DOMContentLoaded', fireContentLoadedEvent, false);
} else {
    pollDoScroll();
}

完整的代码如下:

window.DOMLoadEvents = [];
var addDOMLoadEvent = function(handler) {
    window.DOMLoadEvents[window.DOMLoadEvents.length]=handler
}
var fireContentLoadedEvent = function() {
    if (arguments.callee.loaded) return;
    //让此函数仅仅执行一次
    arguments.callee.loaded = true;
    var handlers = window.DOMLoadEvents,length = handlers.length;
    for (var i=0; i<length; i++) {
        var func = handlers[i];
        func();//执行要在domReady运行的代码
    }
}
var pollDoScroll = function() {
    try {
        document.documentElement.doScroll('left');
    }catch(e) {
        setTimeout(arguments.callee, 10);
        return;
    }
    fireContentLoadedEvent();
}
if (document.addEventListener) {
    document.addEventListener('DOMContentLoaded', fireContentLoadedEvent, false);
} else {
    pollDoScroll();

}

javascript的页面加载及性能优化(兼容IE7)的更多相关文章

  1. 前端开发,页面加载速度性能优化,如何提高web页面加载速度

    一个网页访问速度的快慢,  不仅看它服务器的配置,这里除去你空间主机配置很烂的情况以外,我们从网站开发方面来探讨,前端技术需要从哪些方面提高访问的速度,需要用到哪些技术手段. 文件的加载 图标的加载: ...

  2. Javascript中页面加载完成后优先执行顺序

    Javascript中页面加载完成后优先执行顺序 document优先于windowwindow优先于element //document加载完成执行方法体 document.addEventList ...

  3. webdriver定位页面元素时使用set_page_load_time()和JavaScript停止页面加载

    webdriver定位页面元素时使用set_page_load_time()和JavaScript停止页面加载 原文:https://my.oschina.net/u/2344787/blog/400 ...

  4. 一步一步实现listview加载的性能优化

    listview加载的核心是其adapter,本文针对listview加载的性能优化就是对adpter的优化,总共分四个层次: 0.最原始的加载 1.利用convertView 2.利用ViewHol ...

  5. Javascript在页面加载时的执行顺序【转】

    一.在HTML中嵌入Javasript的方法 直接在Javascript代码放在标记对<script>和</script>之间 由<script />标记的src属 ...

  6. javascript 实现页面加载完再显示页面

    document.onreadystatechange = function () { if (document.readyState == "complete") { docum ...

  7. JavaScript Html页面加载完成

    //一.Html页面加载完成的JS写法 //1. $(function () {     alert("窗体Html页面加载完成方法一"); }); //2. $(document ...

  8. JavaScript Html页面加载完成三种写法

    //一.Html页面加载完成的JS写法 //1. $(function () {     alert("窗体Html页面加载完成方法一"); }); //2. $(document ...

  9. javascript 实现页面加载完的操作

    document.onreadystatechange = function () { if (document.readyState == "complete") {//页面加载 ...

随机推荐

  1. led.c驱动框架

    Makefile: obj-m += led.o ################################################ KERNEL = /home/linux--FS21 ...

  2. android复习-AnsyTask

    AnsyTask是一种类似Thread+Hander机制的处理耗时操作的类, 通过在UI线程中excute()启动操作, 在AnsyTask中 doInBackground()中处理耗时操作(运行在自 ...

  3. XML简单的增改删操作

    XML文件的简单增改删,每一个都可以单独拿出来使用. 新创建XML文件,<?xmlversion="1.0"encoding="utf-8"?> & ...

  4. 关于WebAPI安全认证的问题

    之前项目遇到了一个对外提供API的问题,有些粗浅的想法,抽空记录下. 以下所讨论的都是要解决:谁有资格调用这个API的问题(谁有权限进行这个操作的问题) 为了简化思路,就拿一个查看Java班级的学生举 ...

  5. FIR滤波器的实现方法(转)

    源:http://blog.sina.com.cn/s/blog_493520900102uy26.html 内容来自于上篇博文,第七章,FIR滤波器 http://blog.sina.com.cn/ ...

  6. IFields Interface 定义一个字段集合对象

    Description The Fields object represents a collection of columns in a table. The term field is synon ...

  7. Nexus搭建私服 学习

    为什么要搭建nexus私服 因为有些公司不提供外网给项目组人员,因此就不能使用maven访问远程的仓库地址,所以,有必要再局域网里找一台有外网权限的机器.搭建nexus私服,然后开发人员连接到这台私服 ...

  8. IO口输入输出模式理解

    1.IO输入输出模式 2.有上拉,下拉,弱上拉,推挽,开漏输出:不同的单片机有不同的输出模式 3.以最简单的51单片机为例 P0:开漏型双向IO口,通常需要添加外部上拉电阻 P1~P3:准双向IO口, ...

  9. MOS管常识

    http://anlx27.iteye.com/blog/1583089 学过模拟电路,但都忘得差不多了.重新学习MOS管相关知识,大多数是整理得来并非原创.如有错误还请多多指点! 先上一张图 一. ...

  10. Sping--AOP--XML

    IoC: annotation AOP: XML XML比annotation用的多. beans.xml: <?xml version="1.0" encoding=&qu ...