window.onload 触发时机问题
.markdown-body { line-height: 1.75; font-weight: 400; font-size: 16px; overflow-x: hidden; color: rgba(37, 41, 51, 1) }
.markdown-body h1, .markdown-body h2, .markdown-body h3, .markdown-body h4, .markdown-body h5, .markdown-body h6 { line-height: 1.5; margin-top: 35px; margin-bottom: 10px; padding-bottom: 5px }
.markdown-body h1 { font-size: 24px; line-height: 38px; margin-bottom: 5px }
.markdown-body h2 { font-size: 22px; line-height: 34px; padding-bottom: 12px; border-bottom: 1px solid rgba(236, 236, 236, 1) }
.markdown-body h3 { font-size: 20px; line-height: 28px }
.markdown-body h4 { font-size: 18px; line-height: 26px }
.markdown-body h5 { font-size: 17px; line-height: 24px }
.markdown-body h6 { font-size: 16px; line-height: 24px }
.markdown-body p { line-height: inherit; margin-top: 22px; margin-bottom: 22px }
.markdown-body img { max-width: 100% }
.markdown-body hr { border-top: 1px solid rgba(221, 221, 221, 1); border-right: none; border-bottom: none; border-left: none; margin-top: 32px; margin-bottom: 32px }
.markdown-body code { border-radius: 2px; overflow-x: auto; background-color: rgba(255, 245, 245, 1); color: rgba(255, 80, 44, 1); font-size: 0.87em; padding: 0.065em 0.4em }
.markdown-body code, .markdown-body pre { font-family: Menlo, Monaco, Consolas, Courier New, monospace }
.markdown-body pre { overflow: auto; position: relative; line-height: 1.75 }
.markdown-body pre>code { font-size: 12px; padding: 15px 12px; margin: 0; word-break: normal; display: block; overflow-x: auto; color: rgba(51, 51, 51, 1); background: rgba(248, 248, 248, 1) }
.markdown-body a { text-decoration: none; color: rgba(2, 105, 200, 1); border-bottom: 1px solid rgba(209, 233, 255, 1) }
.markdown-body a:active, .markdown-body a:hover { color: rgba(39, 91, 140, 1) }
.markdown-body table { display: inline-block !important; font-size: 12px; width: auto; max-width: 100%; overflow: auto; border: 1px solid rgba(246, 246, 246, 1) }
.markdown-body thead { background: rgba(246, 246, 246, 1); color: rgba(0, 0, 0, 1); text-align: left }
.markdown-body tr:nth-child(2n) { background-color: rgba(252, 252, 252, 1) }
.markdown-body td, .markdown-body th { padding: 12px 7px; line-height: 24px }
.markdown-body td { min-width: 120px }
.markdown-body blockquote { color: rgba(102, 102, 102, 1); padding: 1px 23px; margin: 22px 0; border-left: 4px solid rgba(203, 203, 203, 1); background-color: rgba(248, 248, 248, 1) }
.markdown-body blockquote:after { display: block; content: "" }
.markdown-body blockquote>p { margin: 10px 0 }
.markdown-body ol, .markdown-body ul { padding-left: 28px }
.markdown-body ol li, .markdown-body ul li { margin-bottom: 0; list-style: inherit }
.markdown-body ol li .task-list-item, .markdown-body ul li .task-list-item { list-style: none }
.markdown-body ol li .task-list-item ol, .markdown-body ol li .task-list-item ul, .markdown-body ul li .task-list-item ol, .markdown-body ul li .task-list-item ul { margin-top: 0 }
.markdown-body ol ol, .markdown-body ol ul, .markdown-body ul ol, .markdown-body ul ul { margin-top: 3px }
.markdown-body ol li { padding-left: 6px }
.markdown-body .contains-task-list { padding-left: 0 }
.markdown-body .task-list-item { list-style: none }
@media (max-width: 720px) { .markdown-body h1 { font-size: 24px } .markdown-body h2 { font-size: 20px } .markdown-body h3 { font-size: 18px } }
本文首发我的博客 - blog.cdswyda.com,转载务必保留作者和出处,以便追溯和错误修正。
本文关键点: window.onload 和 页面上 ajax 的成功回调到底哪个先触发。
答案是不确定。
问题详情
之前遇到一个现象,在父页面弹出一个Dialog加载一个子页面,在onload回调中传递一个参数给子页面,子页面异步ajax成功回调中要使用这个变量。
然而出现的情况是在ajax的成功回调中大多数情况下是取不到这个在onload传来的值,但是偶尔又是可以的。
查阅此Dialog源码,以上逻辑可以进行如下简化。
父页面:
<iframe id="iframe" src="./iframe.html" onload="onLoad()" frameborder="0"></iframe>
<script>
function onLoad() {
console.log('iframe load');
document.getElementsByTagName('iframe')[0].contentWindow.onLoad('load');
}
</script>
子页面:
<script>
$.ajax('./test.json').done(function (a) {
console.log('ajax结果');
console.log(a);
});
function onLoad(e) {
console.log('window onload')
console.log(e);
};
</script>
由于iframe的 onload 即要加载页面的 window.onload ,因此情况可以进一步简化为一个页面中到底是 window.onload 先触发还是 ajax 的成功回调先触发。
测试代码:
<script>
$.ajax('./test.json').done(function (a) {
console.log('ajax结果');
console.log(a);
});
function onLoad(e) {
console.log('window onload')
console.log(e);
};
window.onload = onLoad;
</script>
这个页面除了在测试的script之前引入了jQuery没有其他代码,应该毫无疑问,是 window.onload 先触发,之后才是 ajax 的成功结果。
结果也证明是 window.onload 先触发,上面代码在浏览器运行结果为:
// window onload
// Event {}
// ajax结果
// {}
MDN上关于 window.onload 有如下解释:
The load event fires at the end of the document loading process. At this point, all of the objects in the document are in the DOM, and all the images, scripts, links and sub-frames have finished loading.
那么问题就来了,如果必然是 window.onload 先触发,那么是不可能出现最开始的问题的。
伪解释
继续修改测试代码,再加上一些东西:
<script>
$.ajax('./test.json').done(function (a) {
console.log('ajax结果');
console.log(a);
});
function onLoad(e) {
console.log('window onload')
console.log(e);
};
window.onload = onLoad;
// 其他代码xxx
// 模拟一个一分钟循环
var t1 = new Date().getTime();
while(new Date().getTime() - t1 < 1 * 60 * 1000) {
document.querySelectorAll('*');
}
</script>
写入一个一分钟的循环后,结果发生了改变:
// ajax结果
// {}
// window onload
// Event {}
这么来看就奇怪了呀, ajax 的成功比 window.onload 先触发。
关于这个现象,我也没找到权威的解释。
自己给了一个“合理”的解析:
window.onload 会在当前任务队列的最后一个触发。如最开始的例子,ajax 异步,尚未给出结果,页面需要等待的所有内容已经完成,任务队列为空,因此 window.onload 触发。
而后面这个由于 ajax 后面还有很长的代码要执行,这段代码推迟了 onload 的触发,同时这段代码还未执行完成时,之前异步的ajax已经返回了结果,成功回调的代码已经被加到了任务队列,因此 ajax 回调执行后才触发 window.onload。
再验证
为了进一步验证我上面的想法,那么只要保证页面资源执行完成时,ajax还没有解决即可。
因此还是上面的代码,但是将请求的内容换成一个真实接口,这个真实接口返回的数据更晚即可。
使用php暂停120s再返回结果,代码如下:
<?php
sleep(120);
echo '{"response":"two minutes later."}'
?>
结果却是如上面估计的一样:
// window onload
// Event {}
// ajax结果
// {"response":"two minutes later."}
可以说明之前的“合理”解释确实是合理的。
所以异步的 ajax 和 window.onload 到底哪个会先触发是不确定,和你js代码(或者其他onload要等待的资源,如一个图片加载很慢等)以及这个 ajax 的解决时间有关系。
因此这种情况下的传值就不能以这种方式进行,可以换成更稳妥的方式,如直接跨页面操作或者放在url进行传递。
window.onload 触发时机问题的更多相关文章
- $(document).ready()与 window.onload执行时机
$(document).ready()方法和window.onload方法有相似的功能,但是在执行时机方面是有区别的.window.onload方法是子啊网页中的所有元素(包括元素的所有关联的文件)完 ...
- jQuery $(document).ready()和JavaScript window.onload()事件的区别
一. 在网上查了一下,发现$(document).ready()是在DOM树加载完成时触发,而window.onload()则是在整个页面全部加载完成时触发.下面是一些验证. var start=+n ...
- JS 页面加载触发事件 document.ready和window.onload的区别
document.ready和onload的区别——JavaScript文档加载完成事件页面加载完成有两种事件: 一是ready,表示文档结构已经加载完成(不包含图片等非文字媒体文件): 二是onlo ...
- window.onload() 等待所有的数据加载都完成之后才会触发
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- $(function(){})与window.onload的区别
不太一样window.onload是在页面所有的元素都加载完成后才触发$(function(){})是在页面的dom结构加载完毕后就触发 dom里的内容不一定都已经加载完成比如说一个页面有好多图片 而 ...
- 转载 jquery $(document).ready() 与window.onload的区别
Jquery中$(document).ready()的作用类似于传统JavaScript中的window.onload方法,不过与window.onload方法还是有区别的. 1.执行时间 windo ...
- 锋利的jQuery-4--$(document).ready()和window.onload方法的区别
jQuery中的$(document).ready()和JavaScript中的window.onload方法主要有两个方面的不同: 1.执行时机: onload : 网页中所有的元素和元素的关联文件 ...
- javascript的window.onload()方法和jQuery的$(document).ready()的对比
jQuery中$(document).ready()的作用类似于传统JavaScript中的window.onload方法,不过与window.onload方法还是有区别的. 1.执行时间 windo ...
- [转]jquery $(document).ready() 与window.onload的区别
http://blog.csdn.net/xiebaochun/article/details/36375481 Jquery中$(document).ready()的作用类似于传统JavaScrip ...
- [Javascript]jquery $(document).ready() 与window.onload的区别
引用:http://www.jb51.net/article/21628.htm Jquery中$(document).ready()的作用类似于传统JavaScript中的window.onload ...
随机推荐
- 使用DBeaver连接数据库
下载网站:官网下载 参考链接:使用 DBeaver 连接 OceanBase
- CenOS 安装 mysql 临时密码 处理
数据库 版本 Server version: 8.0.26 MySQL Community Server - GPL:官网下载的包 wget https://cdn.mysql.com//Downlo ...
- CF1601 题解
偶然看这一场的题目,忽然很有感觉,于是写了一下 A 题面 考虑每一位可以单独分开考虑 考虑单独的一位,每次要选 \(m\) 个位置,可能产生贡献的位置就是这位为 1 的数,设数量为 \(x\),则 \ ...
- 线性关系和非线性关系在.net中的应用
在数学中,线性关系和非线性关系是描述两个变量之间函数关系的两种不同类型. 线性关系是指两个变量之间可以用一条直线来表示的关系.具体来说,如果存在一个一次函数 y = kx + b,其中k和b是常数,使 ...
- 用python用户注册和短信验证码逻辑实现案例
一.写代码前分析(逻辑分析OK了才可以顺利成章的敲代码): A.用户发送请求 1.注册账号(用户名不能重复)--按照需求进行判断 2.短信验证码(有效期5分钟)--对短信验证码进行保存 B.用户注册. ...
- Vue 框架下提升加载速度的一些实战经验分享
现在前端的框架有很多,甚至两只手已经数不过来,当然也完全没必要全部都学,还是应该深入的学习一两个被广泛使用的就好.其实我和大部分同学的想法一致,认为最值得我们深究的还是主流的 Vue 和 React. ...
- What...MiniGPT-4居然开源了,提前感受 GPT-4 的图像对话能力!
说在前面的话: 一个月前,OpenAI向外界展示了GPT-4如何通过手绘草图直接生成网站,令当时的观众瞠目结舌. 在GPT-4发布会之后,相信大家对ChatGPT的对话能力已有所了解.圈内的朋友们应该 ...
- PicGo+Github图床配置
为了将 PicGo 设置为使用 GitHub 作为图床,您需要先创建一个 GitHub 仓库用于存储图片,然后在 PicGo 中进行相应的配置.您已经创建了一个仓库,所以让我们来配置 PicGo. 安 ...
- JS深入学习笔记 - 第一章.构造函数原型与原型链
1.构造函数和原型 1.1 概述 在典型的 OOP语言中(如Java),都存在类的概念,类就是对象的模板,对象就是类的实例,但在ES6之前,JS并没有引入类的概念. 在ES6之前,对象不是基于类创建的 ...
- pyinstall打包相对路径问题
pyinstall打包相对路径问题 pyinstaller 打包py文件成exe文件,在没有python的机器上运行,执行打包后的程序,经常会出现程序使用的图标无法显示,程序使用的关联文件无法关联 ...