zoukankan      html  css  js  c++  java
  • jQuery中ready与load事件

    jQuery中ready与load事件(来自慕课网)

    jQuery有3种针对文档加载的方法

    $(document).ready(function() {
        // ...代码...
    })
    //document ready 简写
    $(function() {
        // ...代码...
    })
    $(document).load(function() {
        // ...代码...
    })

    一个是ready一个是load,这两个到底有什么区别呢?

    ready与load谁先执行:
    大家在面试的过程中,经常会被问到一个问题:ready与load那一个先执行,那一个后执行?答案是ready先执行,load后执行。

    DOM文档加载的步骤:
    要想理解为什么ready先执行,load后执行就要先了解下DOM文档加载的步骤:

    (1) 解析HTML结构。
    (2) 加载外部脚本和样式表文件。
    (3) 解析并执行脚本代码。
    (4) 构造HTML DOM模型。//ready
    (5) 加载图片等外部文件。
    (6) 页面加载完毕。//load

    从上面的描述中大家应该已经理解了吧,ready在第(4)步完成之后就执行了,但是load要在第(6)步完成之后才执行。

    结论:

    ready与load的区别就在于资源文件的加载,ready构建了基本的DOM结构,所以对于代码来说应该越快加载越好。在一个高速浏览的时代,没人愿意等待答案。假如一个网站页面加载超过4秒,不好意思,你1/4的用户将面临着流失,所以对于框架来说用户体验是至关重要的,我们应该越早处理DOM越好,我们不需要等到图片资源都加载后才去处理框架的加载,图片资源过多load事件就会迟迟不会触发。

    我们看看jQuery是如何处理文档加载时机的问题:

    jQuery.ready.promise = function( obj ) {
        if ( !readyList ) {
            readyList = jQuery.Deferred();
            if ( document.readyState === "complete" ) {
                // Handle it asynchronously to allow scripts the opportunity to delay ready
                setTimeout( jQuery.ready );
            } else {
                document.addEventListener( "DOMContentLoaded", completed, false );
                window.addEventListener( "load", completed, false );
            }
        }
        return readyList.promise( obj );
    };

    jQuery的ready是通过promise给包装过的,这也是jQuery擅长的手法,统一了回调体系,以后我们会重点谈到。
    可见jQuery兼容的具体策略:针对高级的浏览器,我们当前很乐意用DOMContentLoaded事件了,省时省力。

    那么旧的IE如何处理呢?

    继续看jQuery的方案:

    // Ensure firing before onload, maybe late but safe also for iframes
    document.attachEvent( "onreadystatechange", completed );
    // A fallback to window.onload, that will always work
    window.attachEvent( "onload", completed );
    // If IE and not a frame
    // continually check to see if the document is ready
    var top = false;
    try {
        top = window.frameElement == null && document.documentElement;
    } catch(e) {}
    if ( top && top.doScroll ) {
        (function doScrollCheck() {
            if ( !jQuery.isReady ) {
                try {
                    // Use the trick by Diego Perini
                    // http://javascript.nwbox.com/IEContentLoaded/
                    top.doScroll("left");
                } catch(e) {
                    return setTimeout( doScrollCheck, 50 );
                }
                // detach all dom ready events
                detach();
    
                // and execute any waiting functions
                jQuery.ready();
            }
        })();
    }

        如果浏览器存在 document.onreadystatechange 事件,当该事件触发时,如果 document.readyState=complete 的时候,可视为 DOM 树已经载入。不过,这个事件不太可靠,比如当页面中存在图片的时候,可能反而在 onload 事件之后才能触发,换言之,它只能正确地执行于页面不包含二进制资源或非常少或者被缓存时作为一个备选吧。

    针对IE的加载检测

    Diego Perini 在 2007 年的时候,报告了一种检测 IE 是否加载完成的方式,使用 doScroll 方法调用,详情可见http://javascript.nwbox.com/IEContentLoaded/。
    原理就是对于 IE 在非 iframe 内时,只有不断地通过能否执行 doScroll 判断 DOM 是否加载完毕。在上述中间隔 50 毫秒尝试去执行 doScroll,注意,由于页面没有加载完成的时候,调用 doScroll 会导致异常,所以使用了 try -catch 来捕获异常。
    结论:所以总的来说当页面 DOM 未加载完成时,调用 doScroll 方法时,会产生异常。那么我们反过来用,如果不异常,那么就是页面DOM加载完毕了。

    这都是我们在第一时间内处理ready加载的问题,如果ready在页面加载完毕后呢?

    jQuery就必须针对这样的情况跳过绑定了:

    if ( document.readyState === "complete" ) {
         // Handle it asynchronously to allow scripts the opportunity to delay ready
         setTimeout( jQuery.ready );
     }
    

    直接通过查看readyState的状态来确定页面的加载是否完成了。这里会给一个定时器的最小时间后去执行,主要保证执行的正确。

    慌慌张张 匆匆忙忙 为何生活总是这样 难道说我的理想 就是这样度过一生的时光 不卑不亢 不慌不忙 也许生活应该这样 难道说六十岁以后 再去寻找我想要的自由 其实我也常对自己说 人要学会知足而常乐 可万事都一笑而过 还有什么意思呢
  • 相关阅读:
    随笔2
    随笔
    关于updateElement接口
    随笔1
    本地访问正常,服务器访问乱码 记录
    Redis (error) NOAUTH Authentication required.解决方法
    tomcat启动很慢 停留在 At least one JAR was scanned for TLDs yet contained no TLDs.
    微信公众号消息回复
    微信公众号 报token验证失败
    idea中web.xml报错 Servlet should have a mapping
  • 原文地址:https://www.cnblogs.com/siwy/p/4867567.html
Copyright © 2011-2022 走看看