• ready是先执行的,load后执行,DOM文档的加载步骤


    在jq中在文档载入完毕后有这几种方式去执行指定函数:

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

    $(function(){}) 的方式其实是 $(document).ready() 的简写,具体可以看看jq构造器那块。

    ready与load谁先执行

    这个问题在面试的时候也会经常被提到,ready是先执行的,load后执行,DOM文档的加载步骤:

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

    .ready() 都是作用于 window.onload 事件的。

    jQuery.fn.ready = function( fn ) { // Add the callback jQuery.ready.promise().done( fn ); return this; };

    当调用ready事件时,jq就会把函数添加到一个回调列表中。

    而 .load() 作用的是为每个匹配元素的load事件绑定处理函数。

    $(window).load( function(){ alert("文档加载完毕!"); } ); $("img").load( function(){ alert( "图片[" + this.alt + "]加载完毕!" ); } );

    load的写法也发生了一些改变,1.8版本之后,load就抛弃了,只剩下ajax的load了,它的函数原型:

    jQuery.fn.load = function( url, params, callback ) { //code... return this; }

    因此在高版本中它的使用应该是:

    $('#result').load('ajax/test.html', function() { alert('Load was performed.'); }); ready源码 // readyList.promise() === jQuery.ready.promise() var readyList; jQuery.fn.ready = function( fn ) { // promise后添加回调 jQuery.ready.promise().done( fn ); // 链式 return this; }; jQuery.extend({ // 此判断防止重复触发 isReady: false, // 需要几次jQuery.ready()调用,才会触发promise和自定义ready事件 readyWait: 1, // Hold (or release) the ready event holdReady: function( hold ) { if ( hold ) { // true,延迟次数 +1 jQuery.readyWait++; } else { // 无参数,消减次数 -1 jQuery.ready( true ); } }, // 触发promise和自定义ready事件 ready: function( wait ) { // ready(true)时,消减次数的地方。也能代替干ready()的事 if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { return; } // ready()调用时,标记dom已加载完成 jQuery.isReady = true; // ready(2881064151)能够设置isReady,只能消减默认的那1次 if ( wait !== true && --jQuery.readyWait > 0 ) { return; } // 触发promise,jQuery.fn.ready(fn)绑定函数都被触发 readyList.resolveWith( document, [ jQuery ] ); // 触发自定义ready事件,并删除事件绑定 if ( jQuery.fn.triggerHandler ) { jQuery( document ).triggerHandler( "ready" ); jQuery( document ).off( "ready" ); } } }); // 解绑函数 function completed() { document.removeEventListener( "DOMContentLoaded", completed, false ); window.removeEventListener( "load", completed, false ); jQuery.ready(); } jQuery.ready.promise = function( obj ) { if ( !readyList ) { readyList = jQuery.Deferred(); // 判断执行到这时,是否已经加载完成 if ( document.readyState === "complete" ) { // 不再需要绑定任何监听函数,直接触发jQuery.ready。延迟一会,等代码执行完 setTimeout( jQuery.ready ); } else { // Use the handy event callback document.addEventListener( "DOMContentLoaded", completed, false ); // 个别浏览器情况,错过了事件仍可触发 window.addEventListener( "load", completed, false ); } } return readyList.promise( obj ); }; // 执行。生成deferred对象,绑定好监听逻辑 jQuery.ready.promise();

    readyList = jQuery.Deferred(); 回调列表是 $.Deferred 对象,事件监听通过:

    document.addEventListener( "DOMContentLoaded", completed, false ); window.addEventListener( "load", completed, false );

    为了达到兼容不同浏览器,一个添加到 window 一个添加到 document ,通过 $.isReady 避免多次调用。

    function completed() { document.removeEventListener( "DOMContentLoaded", completed, false ); window.removeEventListener( "load", completed, false ); jQuery.ready(); }

    对事件进行解绑,调用 $.ready() :

    readyList.resolveWith( document, [ jQuery ] );

    执行异步对象里的函数队列。

    load

    load的实现就比较简单, jQuery.fn.load = function( url, params, callback ){} 它几乎与 $.get(url, data, success) 等价,因为它就是通过 $.ajax() 实现的,不同的是它的url可以包含一个空格或多个空格,紧接第一个空格的字符串则是决定所加载内容的 jQuery 选择器:

    $("#result").load("ajax/test.html #container");

    如果执行该方法,则会取回 ajax/test.html 的内容,不过然后, jQuery 会解析被返回的文档,来查找带有容器 ID 的元素。该元素,连同其内容,会被插入带有结果 ID 的元素中,所取回文档的其余部分会被丢弃。

    off = url.indexOf(" "); if ( off >= 0 ) { selector = jQuery.trim( url.slice( off ) ); url = url.slice( 0, off ); }

    最后来看看它ajax部分:

    jQuery.ajax({ url: url, // if "type" variable is undefined, then "GET" method will be used type: type, dataType: "html", data: params }).done(function( responseText ) { // Save response for use in complete callback response = arguments; self.html( selector ? // If a selector was specified, locate the right elements in a dummy div // Exclude scripts to avoid IE 'Permission Denied' errors jQuery("<div>").append( jQuery.parseHTML( responseText ) ).find( selector ) : // Otherwise use the full result responseText ); }).complete( callback && function( jqXHR, status ) { self.each( callback, response || [ jqXHR.responseText, status, jqXHR ] ); });

    self.html() 是使用浏览器的 .innerHTML 属性来解析被取回的文档,并把它插入当前文档。

  • 相关阅读:
    去掉DevExpress gridControl控件表头上的的默认英文字母
    【555】folium 更换底图
    github图片不显示问题解决
    厉害了,自己动手实现 LRU 缓存机制!
    一文搞懂 Netty 的整体流程,还有谁不会?
    PageHelper 分页一直有性能问题?
    left join 后用 on 还是 where,区别大了!
    不推荐别的了,IDEA 自带的数据库工具就很牛逼!
    王炸!!IDEA 2021.1 推出语音、视频功能,边写代码边聊天,我真的服了…
    别再面向 for 循环编程了,Spring 自带的观察者模式就很香!
  • 原文地址:https://www.cnblogs.com/cbryge/p/6210001.html
Copyright © 2020-2023  润新知