深入理解DOM事件类型系列第六篇——加载事件
前面的话
提到加载事件,可能想到了window.onload,但实际上,加载事件是一大类事件,本文将详细介绍加载事件
load
load事件是最常用的一个事件,当页面完全加载后(包括所有图像、javascript文件、CSS文件等外部资源),就会触发window上的load事件
[注意]IE8-浏览器不会为该事件设置srcElement属性,而其他浏览器的target属性指向document
window.onload = function(e){
e = e || event;
var target = e.target || e.srcElement;
//IE8-浏览器返回null,其他浏览器返回document
console.log(target);
}
load事件不仅发生在document对象,还发生在各种外部资源上面。浏览网页就是一个加载各种资源的过程,图像(image)、样式表(style sheet)、脚本(script)、视频(video)、音频(audio)、Ajax请求(XMLHttpRequest)等等。这些资源和document对象、window对象、XMLHttpRequestUpload对象,都会触发load事件
[注意]如果页面从浏览器缓存加载,并不会触发load事件
[注意]要在指定图像的src属性之前先指定事件,图像是从设置src属性之后开始下载
var img = new Image();
img.onload = function(){
document.body.appendChild(img);
}
img.src="http://sandbox.runjs.cn/uploads/rs/26/ddzmgynp/chunfen.jpg";
<iframe id="test" src="http://cnblogs.com" frameborder="0"></iframe>
<script>
test.onload = function(){
console.log(666);
}
</script>
script元素也可以触发load事件,以便开发人员确定动态加载的javascript文件是否加载完毕。与图像不同,只有在设置了script元素的src属性并将该元素添加到文档后,才会开始下载javascript文件。换句话说,指定src属性和指定事件处理程序的先后顺序不重要
[注意]IE8-浏览器不支持该用法
var script = document.createElement('script');
script.onload = function(){
console.log(666);
}
document.body.appendChild(script);
script.src="http://files.cnblogs.com/files/xiaohuochai/excanvas.js";
类似地,link元素可以触发load事件,且无兼容性问题。与script类似,在未指定href属性并将link元素添加到文档之前也不会开始下载样式表
var link = document.createElement('link');
link.rel="stylesheet";
link.onload = function(){
console.log(666);
}
document.getElementsByTagName('head')[0].appendChild(link);
link.href="http://sandbox.runjs.cn/uploads/rs/26/ddzmgynp/style.css";
error
load事件在加载成功时触发,而error事件与之正相反,在加载失败时触发。凡是可以触发load事件的元素,同样可以触发error事件
任何没有通过try-catch处理的错误都会触发window对象的error事件
error事件可以接收三个参数:错误消息、错误所在的URL和行号。多数情况下,只有错误消息有用,因为URL只是给出了文档的位置,而行号所指的代码行既可能出自嵌入的javascript代码,也可能出自外部的文件
要指定onerror事件处理程序,可以使用DOM0级技术,也可以使用DOM2级事件的标准格式
//DOM0级
window.onerror = function(message,url,line){
alert(message);
}
//DOM2级
window.addEventListener("error",function(message,url,line){
alert(message);
});
浏览器是否显示标准的错误消息,取决于onerror的返回值。如果返回值为false,则在控制台中显示错误消息;如果返回值为true,则不显示
//控制台显示错误消息
window.onerror = function(message,url,line){
alert(message);
return false;
}
a; //控制台不显示错误消息
window.onerror = function(message,url,line){
alert(message);
return true;
}
a;
这个事件处理程序是避免浏览器报告错误的最后一道防线。理想情况下,只要可能就不应该使用它。只要能够适当地使用try-catch语句,就不会有错误交给浏览器,也就不会触发error事件
图像也支持error事件。只要图像的src特性中的URL不能返回可以被识别的图像格式,就会触发error事件。此时的error事件遵循DOM格式,会返回一个以图像为目标的event对象
发生error事件时,图像下载过程已经结束,也就是不能再重新下载了。但是,可以在error事件中,重新设置图像的src属性,指向备用图像的地址
var image = new Image();
document.body.appendChild(image);
image.onerror = function(e){
image.src = 'smileBackup.gif';
}
image.src = 'smilex.gif';
abort
元素加载中止时,(如加载过程中按下ESC键,停止加载),触发该事件,常用于图片加载
[注意]只有IE浏览器支持
var image = new Image();
image.onabort = function(){
console.log(111);
}
document.body.appendChild(image);
image.src = 'http://sandbox.runjs.cn/uploads/rs/26/ddzmgynp/chunfen.jpg';
unload
与load事件对应的是unload事件,该事件在文档被完全卸载后触发。刷新页面时,也会触发该事件
chrome/firefox/safari浏览器会阻止alert等对话框,IE浏览器会阻止console.log()等控制台显示
window.onunload = function(e){
//chrome报错,firefox静默失败,IE弹出666
alert(666);
}
window.onunload = function(e){
//chrome和firefox控制台显示666,IE静默失败
console.log(666);
}
在卸载页面的时候,会导致“空事件处理程序”的发生。“空事件处理程序”是指内存中存留的过时不用的事件处理程序,它们是造成Web应用程序内存与性能问题的主要原因。一般来说,最好的做法是在页面卸载之前,先通过onunload事件处理程序移除所有事件处理程序。因此,只要是通过onload事件处理程序添加的东西,最后都应该通过onunload事件处理程序将它们移除
beforeunload
beforeunload事件在关闭网页或刷新网页时触发。它一般地用来防止用户不小心关闭网页
如果要让beforeunload事件生效,必须满足以下两个条件之一:1、事件处理程序返回一个真值;2、事件对象event.returnValue返回一个真值。如果两个条件同时满足,则以第一个条件为准
chrome/safari/firefox在对话框中不显示指定文本,只显示默认文本。而IE浏览器会在对话框中显示返回值或returnValue值
window.onbeforeunload = function(e){
e = e || event;
//IE浏览器显示指定文本,其他浏览器显示默认文本
e.returnValue = '要离开吗?';
}
DOMContentLoaded
window的onload事件会在页面中的一切都加载完毕时触发,但这个过程可能会因为要加载的外部资源过多而颇费周折。而DOMContentLoaded事件则在形成完整的DOM树之后就会触发,而不理会图像、javascript文件、CSS文件或其他资源是否下载完毕。与load事件不同,DOMContentLoaded支持在页面下载的早期添加事件处理程序,这也就意味着用户能够尽早地与页面进行交互
[注意]网页的javascript脚本是同步执行的,所以定义DOMContentLoaded事件的监听函数,应该放在所有脚本的最前面。否则脚本一旦发生堵塞,将推迟触发DOMContentLoaded事件
要处理DOMContentLoaded事件,可以为document或window添加相应的事件处理程序,尽管这个事件会冒泡到window,但它的目标实际上是document
[注意]IE8-浏览器不支持该事件
window.addEventListener('DOMContentLoaded',function(e){
console.log(1);
})
对于不支持该事件的浏览器如IE8-浏览器,可以在页面加载期间设置一个时间为0毫秒的超时调用,且必须作为页面的第一个超时调用
setTimeout(function(){
console.log(1);
},0)
readystatechange
readystatechange事件发生在Document对象和XMLHttpRequest对象,它们的readyState属性发生变化时触发
这个事件的目的是提供与文档或元素的加载状态有关的信息。支持readystatechange事件的每个对象都有一个readyState属性,可能包含下列5个值中的一个
uninitialized(未初始化):对象存在但尚未初始化
loading(正在加载):对象正在加载数据
loaded(加载完毕):对象加载数据完成
interactive(交互):可以操作对象了,但还没有完全加载
complete(完成):对象已经加载完毕
这些状态看起来很直观,但并非所有对象都会经历readyState的这几个阶段。换句话说,如果某个阶段不适用某个对象,则该对象完全可能跳过该阶段;并没有规定哪个阶段适用于哪个对象。显然,这意味着readystatechange事件经常会少于4次,而readyState属性的值也不总是连续的
对于document而言,值为"interactive"的readyState会在与DOMContentLoaded大致相同的时刻触发readystatechange事件。此时,DOM树已经加载完毕,可以安全地操作它了,因此就会进入交互(interactive)阶段。但与此同时,图像及其他外部文件不一定可用
//'interactive' 'complete'
document.onreadystatechange = function(e){
if(document.readyState == 'uninitialized'){
console.log('uninitialized');
}
if(document.readyState == 'loading'){
console.log('loading');
}
if(document.readyState == 'loaded'){
console.log('loaded');
}
if(document.readyState == 'interactive'){
console.log('interactive');
}
if(document.readyState == 'complete'){
console.log('complete');
}
}
在与load事件一起使用时,无法预测两个事件触发的先后顺序。在包含较多或较大的外部资源的页面中,会在load事件触发之前先进入交互阶段;而在包含较少或较小的外部资源的页面中,则很难说readystatechange事件会发生在load事件前面
让问题变得更复杂的是,交互阶段可能会早于也可能会晚于完成阶段出现,无法确保顺序。在包含较多外部资源的页面中,交互阶段更有可能早于完成阶段出现;而在页面中包含较少外部资源的情况下,完成阶段先于交互阶段出现的可能性更大。因此,为了尽可能抢到先机,有必要同时检测交互和完成阶段
document.onreadystatechange = function(){
if(document.readyState == 'interactive' || document.readyState == 'complete'){
console.log('loaded');
document.onreadystatechange = null;
}
}
对于上面的代码来说,当readystatechange事件触发时,会检测document.readyState的值,看当前是否已经进入交互阶段或完成阶段。如果是,则移除相应的事件处理程序以免在其他阶段再执行
另外,IE10-浏览器支持给script元素和link元素触发readystatechange事件,用来确定外部的javascript或css文件是否已经加载完成
var script = document.createElement('script');
script.onreadystatechange = function(){
if( script.readyState == 'loaded' || script.readyState == 'complete'){
console.log('loaded');
script.onreadystatechange = null;
}
}
script.src="js/digit.js";
document.body.appendChild(script);
var link = document.createElement('link');
link.rel="stylesheet";
link.onreadystatechange = function(){
if( link.readyState == 'loaded' || link.readyState == 'complete'){
console.log('loaded');
link.onreadystatechange = null;
}
}
link.href="test.css";
document.getElementsByTagName('body')[0].appendChild(link);
深入理解DOM事件类型系列第六篇——加载事件的更多相关文章
- 深入理解DOM事件类型系列第五篇——文本事件
× 目录 [1]change [2]textInput [3]input[4]propertychange[5]兼容 前面的话 如果DOM结构发生变化,触发的是变动事件:如果文本框中的文本发生变化,触 ...
- 深入理解DOM事件类型系列第三篇——变动事件
× 目录 [1]删除节点 [2]插入节点 [3]特性节点[4]文本节点 前面的话 变动(mutation)事件能在DOM中的某一部分发生变化时给出提示,这类事件非常有用,但都只能使用DOM2级事件处理 ...
- 深入理解DOM事件类型系列第四篇——剪贴板事件
× 目录 [1]定义 [2]对象方法 [3]应用 前面的话 剪贴板操作可能看起来不起眼,但是却十分有用,可以增强用户体验,方便用户操作.本文将详细介绍剪贴板事件 定义 剪贴板操作包括剪切(cut).复 ...
- 深入理解脚本化CSS系列第六篇——脚本化伪元素的6种方法
× 目录 [1]动态样式 [2]CSS类[3]setAttribute()[4]CSSRule对象添加[5]空样式覆盖[6]CSSRule对象删除 前面的话 我们可以通过计算样式来读取伪元素的样式信息 ...
- (转)spring boot实战(第六篇)加载application资源文件源码分析
原文:http://blog.csdn.net/liaokailin/article/details/48878447
- JS事件 加载事件(onload)注意:1. 加载页面时,触发onload事件,事件写在<body>标签内。 2. 此节的加载页面,可理解为打开一个新页面时。
加载事件(onload) 事件会在页面加载完成后,立即发生,同时执行被调用的程序. 注意:1. 加载页面时,触发onload事件,事件写在<body>标签内. 2. 此节的加载页面,可理解 ...
- js 动态加载事件的几种方法总结
本篇文章主要是对js 动态加载事件的几种方法进行了详细的总结介绍,需要的朋友可以过来参考下,希望对大家有所帮助 有些时候需要动态加载javascript事件的一些方法往往我们需要在 JS 中动态添 ...
- 深入理解JS异步编程五(脚本异步加载)
异步脚本加载 阻塞性脚本 JavaScript在浏览器中被解析和执行时具有阻塞的特性,也就是说,当JavaScript代码执行时,页面的解析.渲染以及其他资源的下载都要停下来等待脚本执行完毕 浏览器是 ...
- 从零开始学 Web 之 jQuery(一)jQuery的概念,页面加载事件
大家好,这里是「 从零开始学 Web 系列教程 」,并在下列地址同步更新...... github:https://github.com/Daotin/Web 微信公众号:Web前端之巅 博客园:ht ...
随机推荐
- 多年心愿,终于完成,热泪盈眶啊。。。Adrew NG 的 机器学习
谢谢Andrew老师!谢谢Coursera!谢谢自己!希望这是一个好的开始!希望自己也能使用机器学习来make a better world...
- Nginx http_user_agent 防御 ab 等
日志出现大量: xxxxxxxxxxxxx - - [04/Jul/2013:23:37:49 +0800] "GET /1000.html HTTP/1.0" 200 56471 ...
- Application_Start和Application_End事件执行时间
Application_start: 第一个访问网站的用户会触发该方法. 通常会在该方法里定义一些系统变量,如聊天室的在线总人数统计,历史访问人数统计的初始化等等均可在这里定义. Applicatio ...
- android log写入机制
这几天和华为的leader面试了下.感觉不错.关键是小女.不容易.是技术面啊.我说的不容易不是面试不容易,是说在华为写代码的小女不容易.哥走南闯北这么多年,女人代码写的好真不多. 其实在任何时候,只要 ...
- CodeForces 622C Not Equal on a Segment
预处理p[i],p[i]表示:[p[i],i]这段闭区间上所有数字都是a[i] 询问的时候,如果xi==a[ri]并且p[ri]<=li,一定无解 剩下的情况都是有解的,如果xi!=a[ri], ...
- MySQL中 InnoDB 和 MyISAM 小结
转:http://blog.csdn.net/ithomer/article/details/5136982 部分内容: InnoDB和MyISAM的差别 InnoDB和MyISAM是许多人在使用My ...
- FireBug 调试工具(推荐)
Firebug是网页浏览器 Mozilla Firefox 下的一款开发类扩展,如同一把精巧的瑞士军刀,从各个不同的角度剖析Web页面内部的细节层面,给Web开发者带来很大的便利. 安装如下: 下面是 ...
- bzoj-1834 network 网络扩容 【网络流】
这题就是复习下网络流. #include <bits/stdc++.h> #define rep(i, a, b) for (int i = a; i <= b; i++) #def ...
- git 常用命令--Linus Torvalds
1.git log 显示仓库的历史记录,默认显示所有记录, 1)git log -m,显示最近的几次提交,, 2)git log --pretty=oneline 显示提交hash和注释 -p 按补 ...
- JavaScript------处理Json数据
//JSON相关函数 JSON.parse(); //将JSON字符串转换为JavaScript对象JSON.stringify(); //将JavaScript值转换为JSON字符串 1.//JSO ...