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 属性来解析被取回的文档,并把它插入当前文档。
ready是先执行的,load后执行,DOM文档的加载步骤的更多相关文章
- Javascript中只能在 HTML 输出流中使用 document.write,在文档已加载后使用它(比如在函数中),会覆盖整个文档。
意思就是说,初次加载时如果没有加载document.write,那么再次加载的时候回覆盖掉原来的内容,只显示新加载的内容. <!DOCTYPE html> <html> < ...
- 您只能在 HTML 输出流中使用 document.write。如果您在文档已加载后使用它(比如在函数中),会覆盖整个文档。
刚刚接触JS,看到这句话时一时没搞懂,想了终于有了一些眉目,意思就是在文档加载过后,如果我们用比方说按钮的方式重新加载文档,就会把文档都覆盖: 列如: <!DOCTYPE html> &l ...
- ApiPost的预执行脚本和后执行脚本
ApiPost的预执行脚本和后执行脚本主要是用来定义变量.但是它们有什么区别呢? 预执行脚本 在当前接口发送请求前执行的脚本,可以理解为beforeSend的时候执行. 一般在这里,我们可以设置一些前 ...
- IIS6(Win2003) 使用.net 4.0 后,默认文档失效解决方案。
IIS6(Win2003) 使用.net framework 4.0 后,默认文档失效解决方案. 用.net framework 4.0 开发的WEB项目,但放到iis6 中无法使用默认文档,状况如下 ...
- Javascript动态加载Html元素到页面Dom文档结构时执行顺序的不同
我们有时会通过ajax动态获取一段Html代码,并且将这段代码通过javascript放到页面的Dom结构中去. 而很多时候通过ajax动态获取的Html代码中也包含javascript代码,有一点需 ...
- 执行 vue inspect > output.js 报错,无法加载文件 C:\Users\Administrator\AppData\Roaming\npm\vue.ps1,因为在此系统中禁止执行脚本
无法加载文件 C:\Users\Administrator\AppData\Roaming\npm\vue.ps1,因为在此系统中禁止执行脚本.有关详细信息,请参阅 "get-help ab ...
- 关于electron-vue打包后静态视频文件无法正常加载的问题解决方法
最近在使用electron-builder构建vue项目的时候发现在生产模式下视频可以正常加载并显示,但是一旦打包到开发环境下,视频就读取不出来了,控制台也并没有报错 一开始博主以为是路径问题,在将路 ...
- eclipse 执行main方法 错误: 找不到或无法加载主类
检查环境变量是否正确 JAVA_HOME JAVA的实际安装目录 CLASSPATH .;%JAVA_HOME%\lib;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\ ...
- 使用page object模式抓取几个主要城市的pm2.5并从小到大排序后写入txt文档
#coding=utf-8from time import sleepimport unittestfrom selenium import webdriverfrom selenium.webdri ...
随机推荐
- strust.xml
使用strust2框架,实现跳转,请求对应路径 <?xml version="1.0" encoding="UTF-8" ?> <!DOCTY ...
- 实现Web验证码图片-原理
实现验证码的基础 GDI+ graphics device interface plus的缩写,即图形设备接口.GDI+为开发者提供了一组实现与各种设备(具有图形化能力但不涉及图形细节的设备)进行交互 ...
- CSS中margin和padding的区别
在CSS中margin是指从自身边框到另一个容器边框之间的距离,就是容器外距离.在CSS中padding是指自身边框到自身内部另一个容器边框之间的距离,就是容器内距离. 下面讲解 padding和ma ...
- Dev 控件问题多少
150702 编译BPL_MonitorView.bpl包发现提示找不到cxBarEditItemD16包, =>我将此包和往下的 dxSkin**包都尝试性删除,编译提示要加载包,点击确定, ...
- Redis入门指南
随着互联网业务对性能需求日益强烈,作为Key/Value存储的Redis具有数据类型丰富和性能表现优异的特点.如果能够熟练地驾驭它,不管是把它用做缓存还是存储,对很多大型应用都很多帮助.新浪作为世界上 ...
- three.js入门3
为什么要用three.js Three.js为我们封装了底层的WebGl接口,使我们在无需掌握繁冗的图形学知识的基础下可以轻松的创建三维场景.相比较使用底层的WebGL我们可以使用更少的代码,大大的降 ...
- mark元素
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 解决嵌入WinForm的WPF控件无法显示图片问题
解决办法是在控件初始化时,通过下面方法再次加载图片: ucCanvas.CreateCoordinateImage.Source = GetImageIcon(global::MainApplicat ...
- Redis内存缓存系统入门
网站:http://redis.io/ key-value cache and store data structure server 1. 服务器端 1.1 安装 下载安装包:http://r ...
- windows自动修改ip的bat文件
@echo off title --IP自动设置 -- MODE con: COLS=80 lines=30 color 0a :main cls echo 按提示操作 echo. echo 设置为无 ...