解决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脚本代码往往需要在文档加载完成后才能够去执行,否则可能导致无法获取对象的情况,为了避免这种情况的发生,可以使用以下两种方式: 一.将脚本代码放在网页的底端,这样在运行脚本代 ...
随机推荐
- 「每日五分钟,玩转JVM」:对象内存布局
概览 一个对象根据不同情况可以被划分成两种情况,当对象是一个非数组对象的时候,对象头,实例数据,对齐填充在内存中三分天下,而数组对象中在对象头中多了一个用于描述数组对象长度的部分 对象头 对象头分为两 ...
- 了解css中px、em、rem的区别并使用Flexible实现vue移动端的适配
本人java菜鸟一名,若有错误,还请见谅. 1.px和em和rem的定义和区别 px:px像素,是相对单位,相对于屏幕的分辨率而言,也就是说,当屏幕的分辨率不同那么px相同,实际看到的大小也会不同. ...
- HDU 1223 还是畅通工程(最小生成树prim模板)
一个很简单的prim模板,但虽然是模板,但也是最基础的,也要脱离模板熟练打出来 后期会更新kruskal写法 #include<iostream> #include<cstdio&g ...
- 弄懂goroutine调度原理
goroutine简介 golang语言作者Rob Pike说,"Goroutine是一个与其他goroutines 并发运行在同一地址空间的Go函数或方法.一个运行的程序由一个或更多个go ...
- 010 深入理解Python语言
目录 一.概述 二.计算机技术的演进 2.1 计算机技术的演进过程 三.编程语言的多样初心 3.1 编程语言有哪些? 3.2 不同编程语言的初心和适用对象 3.3 2018年以后的计算环境- 四.Py ...
- IP地址和int互转
/** * @author: yqq * @date: 2019/5/8 * @description: ip地址与int之间互换 * https://mp.weixin.qq.com/s?__biz ...
- FreeSql (十八)导航属性
导航属性是 FreeSql 的特色功能之一,可通过约定配置.或自定义配置对象间的关系. 导航属性有 OneToMany, ManyToOne, ManyToMany, OneToOne, Parent ...
- Java连载32-对象、类及其关系与定义
一.采用面向对象的方式开发一个软件,生命周期之中: (1)面向对象的分析:OOA (2)面向对象的设计:OOD (3)面向对象的编程:OOP 二.类 定义:类在现实世界世界之中是不存在的,是一个模板, ...
- Pytorch-数学运算
引言 本篇介绍tensor的数学运算. 基本运算 add/minus/multiply/divide matmul pow sqrt/rsqrt round 基础运算 可以使用 + - * / 推荐 ...
- 商用hadoop集群的配置命令分布
角色 安装 hdfs配置 yarn配置 hdfs 格式化 启动yarn服务 启动hdfs服务 master yum install hadoop-hdfs-namenode yum install h ...