解决window.onload延迟加载问题
window.onload方法,表示当页面所有的元素都加载完毕,并且所有要请求的资源也加载完毕才触发执行function这个匿名函数里边的具体内容。这样肯定保证了代码在domReady之后执行。使用window.onload方法在文档外部资源不多的情况下不会有什么问题,但是当页面中有大量远程图片或要请求的远程资源时,我们需要让js在点击每张图片时,进行相应的操作,如果此时外部资源还没有加载完毕,点击图片是不会有任何反应的,大大降低了用户体验。那既然window.onload方法不可行,又该怎么做呢?
你肯定想到了jquery中的$(document).ready(function(){})方法了,其实jquery中的domReady应该和window.onload的实现原理是大同小异的。为了解决window.onload的短板,w3c 新增了一个 DOMContentLoaded 事件。
(1)onload实现
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script>
window.onload=function(){
document.getElementById("header").style.color="red";
}
</script>
</head>
<body>
<h1 id="header">我是H1</h1>
<img src="1.jpg" alt="">
<img src="1.jpg" alt="">
<img src="1.jpg" alt="">
<!-- 如果大量图片的时候onload需要等待全部加载完成才能将h1标签给渲染成红色 -->
</body>
</html>
(2)Jquery解决以上问题
$(document).ready()方法和window.onload有什么区别?
(1)、window.onload方法是在网页中所有的元素(包括元素的所有关联文件)完全加载到浏览器后才执行的。
(2)、$(document).ready() 方法可以在DOM包括图片载入就绪时就对其进行操纵,并调用执行绑定的函数。
tip:jquery就是调用了原生JS事件DOMContentLoaded 来实现相同功能
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="jquery.js"></script>
<script>
$(document).ready(function(){
document.getElementById("header").style.color="red";
})
</script>
</head>
<body>
<h1 id="header">我是H1</h1>
<img src="1.jpg" alt="">
<img src="1.jpg" alt="">
<img src="1.jpg" alt="">
<!-- 假设大量远程图片正在加载 -->
</body>
</html>
(3)原生JS事件DOMContentLoaded实现
参考jquery中domReady的实现原理,来看一下javascript中domReady的实现策略。
JavaScript实现domReady功能,【domReady.js】兼容各浏览器通用版本的源代码:
function myReady(fn){
//对于现代浏览器,对DOMContentLoaded事件的处理采用标准的事件绑定方式
if ( document.addEventListener ) {
document.addEventListener("DOMContentLoaded", fn, false);
} else {
IEContentLoaded(fn);
}
//IE模拟DOMContentLoaded
function IEContentLoaded (fn) {
var d = window.document;
var done = false;
//只执行一次用户的回调函数init()
var init = function () {
if (!done) {
done = true;
fn();
}
};
(function () {
try {
// DOM树未创建完之前调用doScroll会抛出错误
d.documentElement.doScroll('left');
} catch (e) {
//延迟再试一次~
setTimeout(arguments.callee, 50);
return;
}
// 没有错误就表示DOM树创建完毕,然后立马执行用户回调
init();
})();
//监听document的加载状态
d.onreadystatechange = function() {
// 如果用户是在domReady之后绑定的函数,就立马执行
if (d.readyState == 'complete') {
d.onreadystatechange = null;
init();
}
}
}
}
粘贴上面代码到新js文件保存。在页面中引入domReady.js文件,引用myReady(回调函数)方法即可。
用原生JS实现跟Jquery的ready相同功能效果:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="domReady.js"></script> <!--引用domReady功能 -->
<script>
myReady(function(){
document.getElementById("header").style.color="red";
})
</script>
</head>
<body>
<h1 id="header">我是H1</h1>
<img src="1.jpg" alt="">
<img src="1.jpg" alt="">
<img src="1.jpg" alt="">
<!-- 假设大量远程图片正在加载 -->
</body>
</html>
很明显,onload事件是要在所有请求都完成之后才执行,而domReady利用hack技术,在加载完dom树之后就能执行,所以domReady比onload执行时间更早,建议采用domReady。
(4)domReady与window.onload延迟差距测试
下面通过一个案例,来比较domReady与window.onload实现的不同,很明显,onload事件是要在所有请求都完成之后才执行,而domReady利用hack技术,在加载完dom树之后就能执行,所以domReady比onload执行时间更早,建议采用domReady。
<!DOCTYPE html>
<html lang="zh-CN"> <head>
<meta charset="utf-8">
<title>domReady与window.onload</title>
<script src="domReady.js"></script>
</head> <body>
<div id="showMsg"></div>
<div>
<img src="http://ww1.sinaimg.cn/large/ae49ba57gy1fe9zofelhdj20xc0xc42s.jpg" alt="">
<img src="http://ww1.sinaimg.cn/large/ae49ba57gy1fe9zofahw3j20m80etq4a.jpg" alt="">
<img src="http://ww1.sinaimg.cn/large/ae49ba57gy1fe9zoi3ny6j20l20dw4gd.jpg" alt="">
<img src="http://ww1.sinaimg.cn/large/ae49ba57gy1fe9zog3tauj20m80et0uw.jpg" alt="">
<img src="http://ww1.sinaimg.cn/large/ae49ba57gy1fe9zofi2o5j20m80ettaq.jpg" alt="">
<img src="http://ww1.sinaimg.cn/large/ae49ba57gy1fe9zohjuvhj20tb0cdwvp.jpg" alt="">
</div>
<script>
var d = document;
var msgBox = d.getElementById("showMsg");
var imgs = d.getElementsByTagName("img");
var time1 = null,
time2 = null;
myReady(function() {
msgBox.innerHTML += "dom已加载!<br>";
time1 = new Date().getTime();
msgBox.innerHTML += "时间戳:" + time1 + "<br>";
});
window.onload = function() {
msgBox.innerHTML += "onload已加载!<br>";
time2 = new Date().getTime();
msgBox.innerHTML += "时间戳:" + time2 + "<br>";
msgBox.innerHTML += "domReady比onload快:" + (time2 - time1) + "ms<br>";
};
</script>
</body> </html>
执行结果对比,发现DomReady比onload快乐2秒左右。
解决window.onload延迟加载问题的更多相关文章
- jQuery基础之(三)jQuery功能函数前缀及与window.onload冲突
1.jQuery功能函数前缀 在javascript中,开发者通常会编写一些小函数来处理各种操作细节,例如在用户提交表单时,要将文本框最前端和最末端的空格内容清理掉.而javascript中没有类似t ...
- JS:window.onload的使用介绍
作者: 字体:[增加 减小] 类型:转载 时间:2013-11-13我要评论 window.onload在某些情况下还是比较实用的,比如加载时执行哪些脚本等等,下面有几个不错的示例,需要的朋友可以参考 ...
- 解决多人开发时使用window.onload的覆盖问题
通用型小函数:解决多人开发时,同时使用window.onload事件所出现的后面的window.onload函数覆盖前面一个window.onload函数的问题. function addLoadEv ...
- 关于window.onload和body onload冲突的解决办法
在学习用js在 页面中动态显示当前时间 和依次读取公告栏信息的 实验中 发现在将两个页面整合时 window.onload=function (){}和 <body onload="d ...
- window.onload和DOMContentLoaded的区别
一.何时触发这两个事件? 1.当 onload 事件触发时,页面上所有的DOM,样式表,脚本,图片,flash都已经加载完成了. 2.当 DOMContentLoaded 事件触发时,仅当DOM加载完 ...
- window.onload和$(document).ready(function(){})的区别
前段时间在面试之前查找并整理了一下window.onload和$(document).ready(function(){})区别,今天有时间更到我的博客上,由于本人资历尚浅,如有不对的地方,还请指正. ...
- window.onload与$(document).ready()的区别
对于很多初学者来说,window.onload出现在代码中的频率非常高,这似乎变成了一种习惯,可是并不知道具体为什么要加这句代码,可以做几个试验对比: 实验一: <script> docu ...
- jquery mobile在页面加载时添加加载中效果 document.ready 和window.onload执行顺序比较
想要添加这个效果,先来弄明白页面的加载和事件执行顺序,看这个简单例子: <html xmlns="http://www.w3.org/1999/xhtml"> < ...
- window.onload用法详解:
网页中的javaScript脚本代码往往需要在文档加载完成后才能够去执行,否则可能导致无法获取对象的情况,为了避免这种情况的发生,可以使用以下两种方式: 一.将脚本代码放在网页的底端,这样在运行脚本代 ...
随机推荐
- 【Spring】对持久层技术的整合
一.持久层技术 二.JdbcTemplate 开发步骤: 1. 导入相关的jar包 2. 配置连接池(数据源) 将参数设置到属性文件中: 3. 创建表 4. 编写实体类 5. Dao层实现 5.1 继 ...
- 详解JAVA字符串类型switch的底层原理
基础 我们现在使用的Java的版本,基本上是都支持String类型的.当然除了String类型,还有int.char.byte.short.enum等等也都是支持的.然而在其底部实现中,还是基于 整型 ...
- 如何使用React搭建项目
1.首先说明node.js.npm.cnpm分别是做什么的? node.js简单的说 Node.js 就是运行在服务端的 JavaScript,安装了node.js默认安装了npm,可以使用npm - ...
- Oracle 11g Rac 用rman实现把本地数据文件迁移到ASM共享存储中
在Oracle Rac环境中,数据文件都是要存放在ASM共享存储上的,这样两个节点才能同时访问.而当你在某一节点下把数据文件创建在本地磁盘的时候,那么在另一节点上要访问该数据文件的时候就会报错,因为找 ...
- 本地代码上传至github
一. 环境及工具 1.下载并安装git版本管理工具 到 http://git-scm.com/downloads 下载并安装git版本管理工具 2.Windows客户端 3.配置github账号密码及 ...
- Java中的java.lang.Class API 详解
且将新火试新茶,诗酒趁年华. 概述 Class是一个位于java.lang包下面的一个类,在Java中每个类实例都有对应的Class对象.类对象是由Java虚拟机(JVM)自动构造的. Class类的 ...
- MySql(一)_利用NHibernate和MySql交互
1.基础配置,添加MySql和nHibernate的引用 (1) 添加引用,导入MySql.data.dll: 利用MySql提供的API操作: (2) 添加引用,导入NHibernate.d ...
- Winform中使用ZedGraph实现曲线图中字体去掉边框
场景 Winforn中设置ZedGraph曲线图的属性.坐标轴属性.刻度属性: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/10 ...
- CentOS7.2防火墙配置
一.查看firewall以及firewall服务的状态. # 查看firewall服务状态 systemctl status firewalld # 查看firewall状态 firewall-cmd ...
- Flink 编程接口
欢迎来 kk大数据,今天分享的是 Flink 提供了哪些编程接口可以给我们开发. 一.数据集类型 现实世界中,所有的数据都是以流式的形态产生的,不管是哪里产生的数据,在产生的过程中都是一条条地生成,最 ...