.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."}

可以说明之前的“合理”解释确实是合理的。

所以异步的 ajaxwindow.onload 到底哪个会先触发是不确定,和你js代码(或者其他onload要等待的资源,如一个图片加载很慢等)以及这个 ajax 的解决时间有关系。

因此这种情况下的传值就不能以这种方式进行,可以换成更稳妥的方式,如直接跨页面操作或者放在url进行传递。

window.onload 触发时机问题的更多相关文章

  1. $(document).ready()与 window.onload执行时机

    $(document).ready()方法和window.onload方法有相似的功能,但是在执行时机方面是有区别的.window.onload方法是子啊网页中的所有元素(包括元素的所有关联的文件)完 ...

  2. jQuery $(document).ready()和JavaScript window.onload()事件的区别

    一. 在网上查了一下,发现$(document).ready()是在DOM树加载完成时触发,而window.onload()则是在整个页面全部加载完成时触发.下面是一些验证. var start=+n ...

  3. JS 页面加载触发事件 document.ready和window.onload的区别

    document.ready和onload的区别——JavaScript文档加载完成事件页面加载完成有两种事件: 一是ready,表示文档结构已经加载完成(不包含图片等非文字媒体文件): 二是onlo ...

  4. window.onload() 等待所有的数据加载都完成之后才会触发

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  5. $(function(){})与window.onload的区别

    不太一样window.onload是在页面所有的元素都加载完成后才触发$(function(){})是在页面的dom结构加载完毕后就触发 dom里的内容不一定都已经加载完成比如说一个页面有好多图片 而 ...

  6. 转载 jquery $(document).ready() 与window.onload的区别

    Jquery中$(document).ready()的作用类似于传统JavaScript中的window.onload方法,不过与window.onload方法还是有区别的. 1.执行时间 windo ...

  7. 锋利的jQuery-4--$(document).ready()和window.onload方法的区别

    jQuery中的$(document).ready()和JavaScript中的window.onload方法主要有两个方面的不同: 1.执行时机: onload : 网页中所有的元素和元素的关联文件 ...

  8. javascript的window.onload()方法和jQuery的$(document).ready()的对比

    jQuery中$(document).ready()的作用类似于传统JavaScript中的window.onload方法,不过与window.onload方法还是有区别的. 1.执行时间 windo ...

  9. [转]jquery $(document).ready() 与window.onload的区别

    http://blog.csdn.net/xiebaochun/article/details/36375481 Jquery中$(document).ready()的作用类似于传统JavaScrip ...

  10. [Javascript]jquery $(document).ready() 与window.onload的区别

    引用:http://www.jb51.net/article/21628.htm Jquery中$(document).ready()的作用类似于传统JavaScript中的window.onload ...

随机推荐

  1. mysql:EXPLAIN

    推荐阅读原文:EXPLAIN用法和结果分析 语法:EXPLAIN SELECT * FROM t1 使用EXPLAIN关键字可以模拟优化器执行SQL查询语句,从而知道MySQL是如何处理你的SQL语句 ...

  2. Unity UGUI的PointerEventData的介绍及使用

    Unity UGUI的PointerEventData的介绍及使用 1. 什么是PointerEventData? PointerEventData是Unity中UGUI系统中的一个重要组件,用于处理 ...

  3. Magick.NET跨平台压缩图片的用法

    //首先NuGet安装:Magick.NET.Core,Magick.NET-Q16-AnyCPUusing ImageMagick; /// <summary> /// 压缩图片 /// ...

  4. Django: You are trying to add a non-nullable field 'name' to mainnav without a default; we can't do that (the database needs something to populate existing rows).

    错误原因: 语句中缺少默认值 class Main(models.Model): img = models.CharField(max_length=255) name = models.CharFi ...

  5. ubuntu下安装mysqlclient报错

    输入以下代码: 1 解决方法: 2 sudo apt-get install libmysqlclient-dev 3 4 再次安装: 5 pip3 install mysqlclient 文章链接: ...

  6. 从序号和确认号理解TCP三次握手

    头部信息 TCP首部存储的数据和建立连接有关,具体每个字段的用途可以参考这一篇文章,其中序号和确认号决定了发送数据的内容. 头部中间部分"保留"和"窗口"中间是 ...

  7. Javascript执行原理 网页引入javascript的三种方式* javascript核心语法 数据类型 Typeof运算符

    Javascript执行原理: 用户端发送请求到服务器端 将js解析出来的数据(用户身份表示)绑定在请求路径中 服务器端获取到参数后会响应客户端 客户端通过浏览器解析响应的数据并将数据展现在浏览器上 ...

  8. Paddle图神经网络训练-PGLBox代码阅读笔记

    图存储部分 paddle/fluid/framework/fleet/heter_ps graph_gpu_wrapper.h GPU图主入口 graph_gpu_ps_table.h GPU图的主要 ...

  9. Go,从命名开始!Go的关键字和标识符全列表手册和代码示例!

    关注TechLeadCloud,分享互联网架构.云服务技术的全维度知识.作者拥有10+年互联网服务架构.AI产品研发经验.团队管理经验,同济本复旦硕,复旦机器人智能实验室成员,阿里云认证的资深架构师, ...

  10. Python colorama 设置控制台、命令行输出彩色文字

    为了方便调试代码,经常会向stdout中输出一些日志,但是大量日志,有时不好定位问题. 使用终端打印特定颜色字符串,可以突出显示关键性的信息,帮助用户更好地识别和理解输出内容. https://pyp ...