javascript的事件加载

来源:互联网 发布:数据库工程师待遇 编辑:程序博客网 时间:2024/05/18 01:54

出处:http://www.cnblogs.com/rubylouvre/archive/2009/08/26/1554204.html

通常来说,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 方法了。

参数描述scrollbarDownDefault. Down scroll arrow is at the specified locationscrollbarHThumbHorizontal scroll thumb or box is at the specified locationscrollbarLeftLeft scroll arrow is at the specified locationscrollbarPageDownPage-down scroll bar shaft is at the specified locationscrollbarPageLeftPage-left scroll bar shaft is at the specified locationscrollbarPageRightPage-right scroll bar shaft is at the specified locationscrollbarPageUpPage-up scroll bar shaft is at the specified locationscrollbarRightRight scroll arrow is at the specified locationscrollbarUpUp scroll arrow is at the specified locationscrollbarVThumbVertical scroll thumb or box is at the specified locationdownComposite reference to scrollbarDownleftComposite reference to scrollbarLeftpageDownComposite reference to scrollbarPageDown.pageLeftComposite reference to scrollbarPageLeft.pageRightComposite reference to scrollbarPageRight.pageUpComposite reference to scrollbarPageUp.rightComposite reference to scrollbarRight.upComposite 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();
}

eg:
<!doctype html><html dir="ltr" lang="zh-CN">  <head id="head">    <meta charset="utf-8"/>    <title>事件加载 by司徒正美</title>    <script type="text/javascript">      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, 1);          return;        }        fireContentLoadedEvent();      };      if (document.addEventListener) {        document.addEventListener('DOMContentLoaded', fireContentLoadedEvent, false);      } else {        pollDoScroll();      }           addDOMLoadEvent(function(){        alert("赶在页面加载完成alert一下!")      });      addDOMLoadEvent(function(){        alert("测试多重加载!")      });      addDOMLoadEvent(function(){        alert("测试多重加载!")      });    </script>  </head>  <body>    <img src="http://images.cnblogs.com/cnblogs_com/rubylouvre/199042/o_s005.jpg" alt="图片1" />    <img src="http://images.cnblogs.com/cnblogs_com/rubylouvre/199042/o_s006.jpg" alt="图片2" />    <img src="http://images.cnblogs.com/cnblogs_com/rubylouvre/199042/o_s007.jpg" alt="图片3" />    <img src="http://images.cnblogs.com/cnblogs_com/rubylouvre/199042/o_s008.jpg" alt="图片4" />    <img src="http://images.cnblogs.com/cnblogs_com/rubylouvre/199042/o_s009.jpg" alt="图片5" />    <table class="filament_table" cellspacing="0" width="700" rules="cols" >      <col class="grey" width="25%"></col>      <col class="yellow"></col>      <thead>        <tr>          <th>            参数          </th>          <th>            描述          </th>        </tr>      </thead>      <tbody>        <tr>          <td>            scrollbarDown          </td>          <td>            Default. Down scroll arrow is at the specified location          </td>        </tr>        <tr>          <td>            scrollbarHThumb          </td>          <td>            Horizontal scroll thumb or box is at the specified location          </td>        </tr>        <tr>          <td>            scrollbarLeft          </td>          <td>            Left scroll arrow is at the specified location          </td>        </tr>        <tr>          <td>            scrollbarPageDown          </td>          <td>            Page-down scroll bar shaft is at the specified location          </td>        </tr>        <tr>          <td>            scrollbarPageLeft          </td>          <td>            Page-left scroll bar shaft is at the specified location          </td>        </tr>        <tr>          <td>            scrollbarPageRight          </td>          <td>            Page-right scroll bar shaft is at the specified location          </td>        </tr>        <tr>          <td>            scrollbarPageUp          </td>          <td>            Page-up scroll bar shaft is at the specified location          </td>        </tr>        <tr>          <td>            scrollbarRight          </td>          <td>            Right scroll arrow is at the specified location          </td>        </tr>        <tr>          <td>            scrollbarUp          </td>          <td>            Up scroll arrow is at the specified location          </td>        </tr>        <tr>          <td>            scrollbarVThumb          </td>          <td>            Vertical scroll thumb or box is at the specified location          </td>        </tr>        <tr>          <td>            down          </td>          <td>            Composite reference to scrollbarDown          </td>        </tr>        <tr>          <td>            left          </td>          <td>            Composite reference to scrollbarLeft          </td>        </tr>        <tr>          <td>            pageDown          </td>          <td>            Composite reference to scrollbarPageDown.          </td>        </tr>        <tr>          <td>            pageLeft          </td>          <td>            Composite reference to scrollbarPageLeft.          </td>        </tr>        <tr>          <td>            pageRight          </td>          <td>            Composite reference to scrollbarPageRight.          </td>        </tr>        <tr>          <td>            pageUp          </td>          <td>            Composite reference to scrollbarPageUp.          </td>        </tr>        <tr>          <td>            right          </td>          <td>            Composite reference to scrollbarRight.          </td>        </tr>        <tr>          <td>            up          </td>          <td>            Composite reference to scrollbarUp.          </td>        </tr>      </tbody>    </table>    <p>我们添加了些图片与表格延缓页面的加载速度</p>  </body></html>

document.addEventListener 事件的最后一个参数  

document.addEventListener("click",doclick,false);

里最后一个属性设置该事件的响应顺序;
true的话将是最先触发
顺序为 addEventListener->标签的onclick事件->document.onclick 
false的话是最后触发
顺序为 标签的onclick事件->document.onclick->addEventListener

0 0