本文首发我的博客 - blog.cdswyda.com,转载务必保留作者和出处,以便追溯和错误修正。

本文关键点: window.onload 和 页面上 ajax 的成功回调到底哪个先触发。

答案是不确定。

问题详情

之前遇到一个现象,在父页面弹出一个Dialog加载一个子页面,在onload回调中传递一个参数给子页面,子页面异步ajax成功回调中要使用这个变量。

然而出现的情况是在ajax的成功回调中大多数情况下是取不到这个在onload传来的值,但是偶尔又是可以的。

查阅此Dialog源码,以上逻辑可以进行如下简化。

父页面:

function onLoad() {

console.log('iframe load');

document.getElementsByTagName('iframe')[0].contentWindow.onLoad('load');

}

子页面:

$.ajax('./test.json').done(function (a) {

console.log('ajax结果');

console.log(a);

});

function onLoad(e) {

console.log('window onload')

console.log(e);

};

由于iframe的 onload 即要加载页面的 window.onload ,因此情况可以进一步简化为一个页面中到底是 window.onload 先触发还是 ajax 的成功回调先触发。

测试代码:

$.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之前引入了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 先触发,那么是不可能出现最开始的问题的。

伪解释

继续修改测试代码,再加上一些东西:

$.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('*');

}

写入一个一分钟的循环后,结果发生了改变:

// ajax结果

// {}

// window onload

// Event {}

这么来看就奇怪了呀, ajax 的成功比 window.onload 先触发。

关于这个现象,我也没找到权威的解释。

自己给了一个“合理”的解析:

window.onload 会在当前任务队列的最后一个触发。如最开始的例子,ajax 异步,尚未给出结果,页面需要等待的所有内容已经完成,任务队列为空,因此 window.onload 触发。

而后面这个由于 ajax 后面还有很长的代码要执行,这段代码推迟了 onload 的触发,同时这段代码还未执行完成时,之前异步的ajax已经返回了结果,成功回调的代码已经被加到了任务队列,因此 ajax 回调执行后才触发 window.onload。

再验证

为了进一步验证我上面的想法,那么只要保证页面资源执行完成时,ajax还没有解决即可。

因此还是上面的代码,但是将请求的内容换成一个真实接口,这个真实接口返回的数据更晚即可。

使用php暂停120s再返回结果,代码如下:

sleep(120);

echo '{"response":"two minutes later."}'

?>

结果却是如上面估计的一样:

// window onload

// Event {}

// ajax结果

// {"response":"two minutes later."}

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

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

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

php window.onload,window.onload 触发时机问题相关推荐

  1. onLoad和onShow触发时机及区别

    一直搞不清楚onLoad和onShow的区别,今天请教了同事,先记录下来,不对请指正! onLoad触发情况 1. 首次进入该页面加载触发 2. 通过uni.navigateTo(),uni.redi ...

  2. script标签的onload事件的触发时机

    onload事件在资源被加载完成后会被触发.对于script标签,在外部js文件被加载后代码会被立即执行.那么,外部js文件中的代码和该script标签的onload回调函数,它们的执行顺序是怎样的呢 ...

  3. html标签onload,支持onload事件的HTML标签有哪些

    支持onload事件的HTML标签有:"body"."frame"."frameset"."iframe"." ...

  4. JS字符串 window.open() window.opener window.name window对象总结

    晚上总结了一下,发上来分享: 字符串 window.open()  window.opener  window.name  window对象等的一点总结  http://download1.csdn. ...

  5. java串口通信DataRecive_串口通信之DataReceive事件触发时机

    环境:Windows PC.本机虚拟COM2连接COM3.串口调试助手COM2发数据 图1 1> ReceivedBytesThreshold为默认值1:2> 一次发送41个字节:3> ...

  6. Js中的window.parent ,window.top,window.self 详解

    在应用有frameset或者iframe的页面时,parent是父窗口,top是最顶级父窗口(有的窗口中套了好几层frameset或者iframe),self是当前窗口, opener是用open方法 ...

  7. js中Window跟window的区别

    昨天一个朋友问我Window跟window的区别: window.name=1;console.log(Window.name);//Windowconsole.log(window.name);// ...

  8. JS的window.parent ,window.top,window.self

    1.简述 在应用有frameset或者iframe的页面时, parent是父窗口, top是最顶级父窗口, self是当前窗口, 2.window.self 功能:是对当前窗口自身的引用.它和win ...

  9. JS 关于(function( window, undefined ) {})(window)写法的理解

    (function( window, undefined ) {})(window); 这个,为什么要将window和undefined作为参数传给它? (function( $, undefined ...

  10. window.parent ,window.top,window.self 详解

    转载:Js中的window.parent ,window.top,window.self 详解 在应用有frameset或者iframe的页面时,parent是父窗口,top是最顶级父窗口(有的窗口中 ...

最新文章

  1. python svm超参数_grid search 超参数寻优
  2. 磁盘管理及文件系统管理
  3. js中变量和jsp中java代码中变量互相访问解决方案
  4. AbstractListView源码分析8
  5. 单时隙灵敏度有什么影响_英国大学设计出低价开源单分子显微镜
  6. git指令如何葱master转到dev_小姐姐用动画图解Git命令,一看就懂!
  7. 全国多地元旦迎雾霾天气 京津冀霾明天短暂减弱
  8. jupyter notebook 中文乱码问题解决
  9. linux oracle 分号引起大错误
  10. GitHub高赞,一款足以取代迅雷的开源下载工具
  11. 现成轮子OSAL操作系统抽象层的移植
  12. 如何看到并删除电脑的操作记录
  13. yum 装包时,提示Peer cert cannot be verified or peer cert invalid
  14. vscode快捷键快速打开终端到当前目录打开的文件位置
  15. Kafka-安装和使用
  16. 计算机黑屏但是有鼠标,电脑黑屏但是鼠标能动解决方法
  17. 基于python机票预定系统_机票预订系统课程设计.doc
  18. 爱奇艺、腾讯、优酷同日宣布:全面取消超前点播
  19. Python安装和导入cv库
  20. 最简洁的Git的基本操作

热门文章

  1. oracle distinct关键字过滤掉重复记录
  2. “开源”将成为物联网开发生态链的标准
  3. Swift 烧脑体操(五)- Monad
  4. Oracle 11g 错误:ORA-28002: the password will expire within 7 days 解决方法
  5. postgresql-9.3.0级联复制搭建及简单配置
  6. [教程] 谈谈网页设计中的字体应用 (2) serif 和 sans-serif
  7. 帆软css修改按钮立体,FineReport 控件的 CSS 样式
  8. linux qt creator git,Building Qt Creator from Git/zh
  9. 优化mysql服务器硬件包括_MySQL优化之一:服务器硬件和操作系统
  10. 取石头游戏 c语言,[HNOI2010]取石头游戏(博弈论+贪心)