zoukankan      html  css  js  c++  java
  • window.onload加载的多种解决方案

    使用JavaScript操纵DOM,必须等待DOM加载完毕才可以执行代码,但window.onload有个坏处,它非要等到页面中的所有图片及视频加载完毕才会触发load事件。结果就是一些本来应该在打开时隐藏起来的元素,由于网络延迟,在页面打开时仍然会出现,然后又会突然消失,让用户觉得莫名其妙。我们想做的就是寻找一种方法来确定DOM被完全的加载时不用等待所有那些讨厌的图片加载完毕。必须与这种丑陋的闪烁告别!

    我这里整理出针对onload事件的七种方案。

    第七种方案是我们最终的解决方案,也是完美的解决方案。

    三 ~ 六 的解决方案只解决了window.onload加载多个方法,但是还没有解决图片的等待加载问题,还有它们只兼容IE和FF。

    定义和用法 
    onload 事件会在页面或图像加载完成后立即发生。

    语法

    onload=”SomeJavaScriptCode”

    支持该事件的 HTML 标签:

    1
    <body>, <frame>, <frameset>, <iframe>, <img>, <link>, <script>

    支持该事件的 JavaScript 对象:

    image, layer, window实例

    第一种:

    1
    2
    3
    function loadFunction(){   
      alert("hello!");
    }

    1
    <body onload="loadFunction()">

    第二种:

    1
    2
    3
    4
    window.onload = loadFunction;   
    function loadFunction(){   
    alert("hello!");
    }

    第三种:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    function firstFunction(){
    alert("hello firstFun !");
    }
    function secondFunction(){
    alert("hello secondFun !");
     
    }
    window.onload = function(){   
       firstFunction();   
       secondFunction();   
    }

    第四种:通用的做法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    function firstFunction(){
    alert("hello firstFun !");
    }
    function secondFunction(){
    alert("hello secondFun !");
     
    }
     
    function addLoadEvent(func) {   
      var oldonload = window.onload;   
      if (typeof window.onload != 'function') {   
          window.onload = func;   
      } else {     
          window.onload = function() {   
             oldonload();   
             func();   
          }   
      }   
    }  
     
    //测试  
    addLoadEvent(firstFunction);
    addLoadEvent(secondFunction);

    addLoadEvent工作流程:

    把现有的window.onload事件处理函数的值存入变量oldonload。

    如果在这个处理函数上还没有绑定任何函数,就像平时那样把新函数添加给它;

    如果在这个处理函数已经绑定了一些函数,就把函数追回到现有指令未尾。

    浏览器加载html内容是自上而下的(默认),而JS一般是在哪里引入——想想如果JS里面包含了一些即时执行指令,

    它会操作根本不存在元素节点(因为还没有加载完)会有什么后果?结果就是出错。

    addLoadEvent可以实现无论有多少个函数,都能让它们同时和window.onload事件绑定。

    第五种; 推荐

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    function a(){   
      alert("a");   
    }   
     
    function b(){   
      alert("b");   
    }
     
     
    function addEvent(obj,EventName,callBack){//给对象添加事件   
      if(obj.addEventListener){   //FF
         obj.addEventListener(EventName,callBack,false);   
      }else if(obj.attachEvent){//IE   
         obj.attachEvent('on'+EventName,callBack);   
      }else{   
         obj["on"+EventName]=callBack;    
      }   
    }    
    //测试  
    addEvent(window,"load",a);   
    addEvent(window,"load",b);

    第六种:推荐

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    function a(){   
     alert("a");   
    }   
     
    function b(){   
     alert("b");   
    }
    // Please note: this file contains snippets for comparison   
    // it is not self-contained or ready-to-use code as such     
    function addLoadListener(fn)   
    {   
       if (typeof window.addEventListener != 'undefined')  
       {   
       window.addEventListener('load', fn, false);   
       }   
       else if (typeof document.addEventListener != 'undefined')   
       {   
       document.addEventListener('load', fn, false);   
       }   
       else if (typeof window.attachEvent != 'undefined')
       {   
       window.attachEvent('onload', fn);   
       }   
       else  
       {   
       var oldfn = window.onload;   
       if (typeof window.onload != 'function')   
       {   
       window.onload = fn;   
       }   
       else  
       {   
       window.onload = function()   
          {   
          oldfn();   
          fn();   
          };   
       }   
      }   
    } 
     
    //测试
    addLoadListener(a);
    addLoadListener(b);

    第七种:最完美的解决方案

    建立一个独立的通用解决方案,兼容各种浏览器,任何人都可以使用,而无需一个具体的框架。

    最初的完整解决方案:http://dean.edwards.name/weblog/2006/06/again/

    一个独立的通用解决方案 :http://www.thefutureoftheweb.com/blog/adddomloadevent.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
     
    /*
     * (c)2006 Jesse Skinner/Dean Edwards/Matthias Miller/John Resig
     * Special thanks to Dan Webb's domready.js Prototype extension
     * and Simon Willison's addLoadEvent
     *
     * For more info, see:
     * http://www.thefutureoftheweb.com/blog/adddomloadevent
     * http://dean.edwards.name/weblog/2006/06/again/
     * http://www.vivabit.com/bollocks/2006/06/21/a-dom-ready-extension-for-prototype
     * http://simon.incutio.com/archive/2004/05/26/addLoadEvent
     * 
     *
     * To use: call addDOMLoadEvent one or more times with functions, ie:
     
     * addDOMLoadEvent的调用方法,如下:
     *    function something() {
     *       // do something
     *    }
     *    addDOMLoadEvent(something);
     *
     *    addDOMLoadEvent(function() {
     *        // do other stuff
     *    });
     *
     */
     
    addDOMLoadEvent = (function(){
     
        // create event function stack
        var load_events = [],
            load_timer,
            script,
            done,
            exec,
            old_onload,
            init = function () {
                done = true;
                 /*//停止调用计时器*/
                // kill the timer
                clearInterval(load_timer);
     
                // execute each function in the stack in the order they were added
                while (exec = load_events.shift())
                    exec();
     
                if (script) script.onreadystatechange = '';
            };
     
        return function (func) {
            // if the init function was already ran, just run this function now and stop
            if (done) return func();
     
            if (!load_events[0]) {
     
                // for Mozilla/Opera9
       /* 
           DOMContentLoaded是firefox下特有的Event, 当所有DOM解析完以后会触发这个事件。
          注册DOMContentLoaded事件,如果支持的话
       */
                if (document.addEventListener)
                    document.addEventListener("DOMContentLoaded", init, false);
     
                // for Internet Explorer
       /*
         对于IE则使用条件注释,并使用script标签的defer属性
                  IE中可以给script标签添加一个defer(延迟)属性,这样,标签中的脚本只有当DOM加载完毕后才执行*/
     
                /*@cc_on @*/
                /*@if (@_win32)
                    document.write("<script id=__ie_onload defer src=//0><\/scr"+"ipt>");
                    script = document.getElementById("__ie_onload");
                    script.onreadystatechange = function() {
                        if (this.readyState == "complete")
                            init(); // call the onload handler
                    };
                /*@end @*/
     
                // for Safari
          /*
        但对于Safari,我们需要使用setInterval方法不断检测document.readyState
                 当为loaded或complete的时候表明DOM已经加载完毕 
       */
     
                if (/WebKit/i.test(navigator.userAgent)) { // sniff
                    load_timer = setInterval(function() {
                        if (/loaded|complete/.test(document.readyState))
                            init(); // call the onload handler
                    }, 10);
                }
     
                // for other browsers set the window.onload, but also execute the old window.onload
                old_onload = window.onload;
                window.onload = function() {
                    init();
                    if (old_onload) old_onload();
                };
            }
     
            load_events.push(func);
        }
    })();

    方案七的演示:

  • 相关阅读:
    Powershell数据处理
    Powershell About Active Directory Group Membership of a domain user
    Powershell About Active Directory Server
    Oracle Schema Objects——Tables——TableStorage
    Oracle Schema Objects——Tables——TableType
    English Grammar
    Oracle Database Documentation
    Oracle Schema Objects——Tables——Oracle Data Types
    Oracle Schema Objects——Tables——Overview of Tables
    What is Grammar?
  • 原文地址:https://www.cnblogs.com/xx_cs/p/2143406.html
Copyright © 2011-2022 走看看