zoukankan      html  css  js  c++  java
  • 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 属性来解析被取回的文档,并把它插入当前文档。

  • 相关阅读:
    Serialize and Deserialize Binary Tree
    sliding window substring problem汇总贴
    10. Regular Expression Matching
    《深入理解计算机系统》(CSAPP)读书笔记 —— 第七章 链接
    程序员如何写一份合格的简历?(附简历模版)
    9个提高代码运行效率的小技巧你知道几个?
    《深入理解计算机系统》(CSAPP)读书笔记 —— 第六章 存储器层次结构
    24张图7000字详解计算机中的高速缓存
    《深入理解计算机系统》(CSAPP)实验四 —— Attack Lab
    《深入理解计算机系统》(CSAPP)读书笔记 —— 第五章 优化程序性能
  • 原文地址:https://www.cnblogs.com/cbryge/p/6210001.html
Copyright © 2011-2022 走看看