在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 属性来解析被取回的文档,并把它插入当前文档。

ready是先执行的,load后执行,DOM文档的加载步骤的更多相关文章

  1. Javascript中只能在 HTML 输出流中使用 document.write,在文档已加载后使用它(比如在函数中),会覆盖整个文档。

    意思就是说,初次加载时如果没有加载document.write,那么再次加载的时候回覆盖掉原来的内容,只显示新加载的内容. <!DOCTYPE html> <html> < ...

  2. 您只能在 HTML 输出流中使用 document.write。如果您在文档已加载后使用它(比如在函数中),会覆盖整个文档。

    刚刚接触JS,看到这句话时一时没搞懂,想了终于有了一些眉目,意思就是在文档加载过后,如果我们用比方说按钮的方式重新加载文档,就会把文档都覆盖: 列如: <!DOCTYPE html> &l ...

  3. ApiPost的预执行脚本和后执行脚本

    ApiPost的预执行脚本和后执行脚本主要是用来定义变量.但是它们有什么区别呢? 预执行脚本 在当前接口发送请求前执行的脚本,可以理解为beforeSend的时候执行. 一般在这里,我们可以设置一些前 ...

  4. IIS6(Win2003) 使用.net 4.0 后,默认文档失效解决方案。

    IIS6(Win2003) 使用.net framework 4.0 后,默认文档失效解决方案. 用.net framework 4.0 开发的WEB项目,但放到iis6 中无法使用默认文档,状况如下 ...

  5. Javascript动态加载Html元素到页面Dom文档结构时执行顺序的不同

    我们有时会通过ajax动态获取一段Html代码,并且将这段代码通过javascript放到页面的Dom结构中去. 而很多时候通过ajax动态获取的Html代码中也包含javascript代码,有一点需 ...

  6. 执行 vue inspect > output.js 报错,无法加载文件 C:\Users\Administrator\AppData\Roaming\npm\vue.ps1,因为在此系统中禁止执行脚本

    无法加载文件 C:\Users\Administrator\AppData\Roaming\npm\vue.ps1,因为在此系统中禁止执行脚本.有关详细信息,请参阅 "get-help ab ...

  7. 关于electron-vue打包后静态视频文件无法正常加载的问题解决方法

    最近在使用electron-builder构建vue项目的时候发现在生产模式下视频可以正常加载并显示,但是一旦打包到开发环境下,视频就读取不出来了,控制台也并没有报错 一开始博主以为是路径问题,在将路 ...

  8. eclipse 执行main方法 错误: 找不到或无法加载主类

    检查环境变量是否正确 JAVA_HOME JAVA的实际安装目录 CLASSPATH .;%JAVA_HOME%\lib;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\ ...

  9. 使用page object模式抓取几个主要城市的pm2.5并从小到大排序后写入txt文档

    #coding=utf-8from time import sleepimport unittestfrom selenium import webdriverfrom selenium.webdri ...

随机推荐

  1. PHP 一个表单多个提交按钮,处理不同的业务逻辑

    <?phpini_set("error_reporting","E_ALL & ~E_NOTICE");?> <head>< ...

  2. javascript优化--14模式2(DOM和浏览器模式)

    远程脚本 XMLHttpRequest JSONP 和XHR不同,它不受同域的限制: JSONP请求的可以是任意的文档: 请求的URL通常格式为http://example.js?calback=Ca ...

  3. Swift3.0语言教程分割字符串与截取字符串

    Swift3.0语言教程分割字符串与截取字符串 Swift3.0语言教程分割字符串 如果想要快速的创建一个数组,我们可以将字符串进行分割,分割后的内容将会生成一个数组.在NSString中有两个分割字 ...

  4. Java 16进制、unicode互转

    package service; import java.util.regex.Matcher; import java.util.regex.Pattern; public class CodeCh ...

  5. VMware 锐捷 NAT模式的服务自动关闭的解决办法

    之前一直搞不定VMware和锐捷的问题,校园网,你懂的. 后来发现,使用NAT模式联网时,锐捷会间隔性地终结windows系统的那个关于NAT联网的服务,你可以在计算机管理 - 服务,找到一个写有NA ...

  6. three.js 显示一条线

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  7. 【oracle】解锁oracle用户,unlock

    解除oracle用户的锁定状态,例如oracle数据库建立测试实例时默认建立的scott用户,一开始是处于locked状态的,现在我们需要将其解锁,步骤如下: (1)在cmd中登录sqlplus,例如 ...

  8. [linux]unixODBC的安装配置说明

    什么是unixODBC: ODBC(Open Database Connect)是由Microsoft 公司于1991 年提出的一个开放的,用于访问数据库的统一接口规范. unixODBC的是为非Wi ...

  9. Android入门第八篇之GridView(九宫图)

    本文来自http://blog.csdn.net/hellogv/ GridView跟ListView都是比较常用的多控件布局,而GridView更是实现九宫图的首选!本文就是介绍如何使用GridVi ...

  10. 解决JS浮点数(小数)计算加减乘除的BUG

    在JavaScript中输出下面这些数值(注意不能作为字符串输出):0.1000000000000000000000000001(28位小数).0.10000000000000000000000000 ...