解决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脚本代码往往需要在文档加载完成后才能够去执行,否则可能导致无法获取对象的情况,为了避免这种情况的发生,可以使用以下两种方式: 一.将脚本代码放在网页的底端,这样在运行脚本代 ...
随机推荐
- HDU 1015 Safecracker (DFS)
题意:给一个数字n(n<=12000000)和一个字符串s(s<=17),字符串的全是有大写字母组成,字母的大小按照字母表的顺序,比如(A=1,B=2,......Z=26),从该字符串中 ...
- Spring Cloud Alibaba | 微服务分布式事务之Seata
Spring Cloud Alibaba | 微服务分布式事务之Seata 本篇实战所使用Spring有关版本: SpringBoot:2.1.7.RELEASE Spring Cloud:Green ...
- Go语言标准库之strconv
Go语言中strconv包实现了基本数据类型和其字符串表示的相互转换. strconv包 strconv包实现了基本数据类型与其字符串表示的转换,主要有以下常用函数: Atoi().Itia().pa ...
- MYSQL之B+TREE索引原理
1.什么是索引? 索引:加速查询的数据结构. 2.索引常见数据结构 顺序查找: 最基本的查询算法-复杂度O(n),大数据量此算法效率糟糕. 二叉树查找:(binary tree search): O( ...
- Docker下Jedis体验
jedis是redis的java版本的客户端实现,本文通过一些web请求&响应的实例展示了jedis的基本用法: 开始编码前我们先把环境准备好,总共两个server,对应两个docker容器: ...
- apache ignite系列(六): 服务网格
简介 服务网格本质上还是远程方法调用(RPC),而在ignite中注册的服务本质体现还是以cache的形式存在,集群中的节点可以相互调用部署在其它节点上的服务,而且ignite集群会负责部署服务的 ...
- 大数据平台搭建 - cdh5.11.1 - hue安装及集成其他组件
一.简介 hue是一个开源的apache hadoop ui系统,由cloudear desktop演化而来,最后cloudera公司将其贡献给了apache基金会的hadoop社区,它基于pytho ...
- Charles 破解版免费下载和注册安装教程
本文参考:[Charles 破解版免费下载和注册安装教程](https://www.axihe.com/tools/charles/charles/free-use.html) **软件开发不易,请尽 ...
- Linux下Eclipse以及Java环境安装教程[小白化](2019-9)
Linux下安装Eclipse以及Java 一.前言 许久未用Eclipse, Ubuntu上也没装Eclipse, 今天安装发现, 好多东西都忘了. 不过经过一番查找(百度, csdn) 终于还是安 ...
- 实践APP安全性检测(一):APK反编译
1.概述 APP安全性一般可以从以下几方面进行考量: 以及其他一些杂项(或者通用并不局限于APP的安全项): 本文讨论反编译问题. 2.APK反编译 安卓开发的APP,如果不做任何处理是很容易被反编译 ...