.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. Matlab2021a打包jar包问题(linux、windows)

    都有chatgpt了,实在不想写博客....不过还是记录一下问题吧. 我们在用matlab打包jar包的时候,经常会出现打包出错的问题,但无非注意以下几点就行了: 1.打包方式 这个还是很简单的,而且 ...

  2. Pandas: title函数的作用

    代码演示 将首字母大写,其余小写 效果演示 参考链接 https://www.w3resource.com/pandas/series/series-str-title.php

  3. OpenCV实战:从图像处理到深度学习的全面指南

    本文深入浅出地探讨了OpenCV库在图像处理和深度学习中的应用.从基本概念和操作,到复杂的图像变换和深度学习模型的使用,文章以详尽的代码和解释,带领大家步入OpenCV的实战世界. 1. OpenCV ...

  4. 数据分析师如何用SQL解决业务问题?

    本文来自问答. 提问:数据分析人员需要掌握sql到什么程度? 请问做一名数据分析人员,在sql方面需要掌握到什么程度呢?会增删改查就可以了吗?还是说关于开发的内容也要会?不同阶段会有不同的要求吗? 正 ...

  5. 概率dp_C++详解

    引入 概率 DP 用于解决概率问题与期望问题,建议先对概率和期望的内容有一定了解.一般情况下,解决概率问题需要顺序循环,而解决期望问题使用逆序循环,如果定义的状态转移方程存在后效性问题,还需要用到 高 ...

  6. vite 找不到依赖模块:[plugin:vite:dep-pre-bundle]

    问题描述: 运行项目时,出现[plugin:vite:dep-pre-bundle] 错误.这种问题一般为依赖的包未正常配置相关字段,导致vite无法找到包的入口. 遇到这种模块内.找不到引用模块的, ...

  7. 记一次weak_up函数绕过

    2023 蓝帽杯CTF LovePHP 因为比赛已经结束,所以复现环境是从本地进行复现,这次比赛本来排名挺靠前的,原本总排名是60多名,赛区排名30多名,本来是以为有希望进入半决赛的,但是没想到比赛结 ...

  8. github.com/yuin/gopher-lua 踩坑日记

    本文主要记录下在日常开发过程中, 使用 github.com/yuin/gopher-lua 过程中需要注意的地方. 后续遇到其他的需要注意的事项再补充. 1.加载LUA_PATH环境变量 在实际开发 ...

  9. crontab定时任务不执行的一些原因总结

    参考博文地址: https://www.jb51.net/article/154290.htm声明:本文章是在以上地址博文基础上进行整理学习,如有侵权,请联系博主删除,感谢知识共享,一起进步,加油鸭 ...

  10. 杰哥教你面试之一百问系列:java中高级多线程concurrent的使用

    目录 问题1:什么是ConcurrentHashMap?它与HashMap的区别是什么? 问题2:什么是CopyOnWriteArrayList?它适用于什么样的场景? 问题3:什么是Blocking ...