如何通过JavaScript检测window.open打开的页面是否加载完成?
问题描述
我尝试了多种检测新窗口加载完成的方案,但均未生效:
尝试方案1:监听子窗口DOMContentLoaded事件
<!DOCTYPE html> <html> <head> <title>Opening window with JS</title> <script> const openWindow = () => { const win = window.open('', '_blank', 'top=20, left=20, width=200, height=200'); win.document.addEventListener('DOMContentLoaded', () => { console.info('Child window loaded'); win.document.body.style.background = 'hotpink'; }); } document.addEventListener('DOMContentLoaded', (_) => { document.getElementById('open').addEventListener('click', (_) => openWindow()) }) </script> </head> <body> <button id="open">Open window</button> </body> </html>
打开窗口后控制台无日志输出,页面背景也未改变。
尝试方案2:使用win.onload属性
const openWindow = () => { const win = window.open('', '_blank', 'top=20, left=20, width=200, height=200'); win.onload = () => { console.info('Child window loaded'); win.document.body.style.background = 'hotpink'; }; } document.addEventListener('DOMContentLoaded', (_) => { document.getElementById('open').addEventListener('click', (_) => openWindow()) })
该方案同样无效。
尝试方案3:在子窗口HTML中嵌入加载逻辑
const openWindow = () => { const win = window.open('', '_blank', 'top=20, left=20, width=200, height=200'); win.document.write(` <!DOCTYPE html> <html> <head> <title>Child window</title> <script> const handleOnLoad = () => { console.info('Child window loaded'); window.body.style.background = 'hotpink'; } </script> </head> <body onload="handleOnLoad"> </body> </html> `); } document.addEventListener('DOMContentLoaded', (_) => { document.getElementById('open').addEventListener('click', (_) => openWindow()) })
问题仍未解决,求可行的处理办法。
解决方案
你的问题源于三个核心细节错误,修正后即可解决:
1. 空窗口的时序问题
当用window.open('', '_blank')打开空窗口时,浏览器会快速完成初始空白页面的加载,此时再绑定DOMContentLoaded或onload事件,事件已经触发过,导致监听无效。
2. 子窗口嵌入代码的语法错误
第三个方案存在两处错误:
window.body是错误写法,正确应为document.bodyonload="handleOnLoad"缺少调用括号,需改为onload="handleOnLoad()"
3. 未关闭文档流
调用win.document.write()后,必须执行win.document.close(),否则浏览器会认为文档仍在写入中,不会触发onload事件。
正确实现方式(二选一即可)
方式一:父窗口绑定加载事件
const openWindow = () => { const win = window.open('', '_blank', 'top=20, left=20, width=200, height=200'); // 先写入子窗口内容 win.document.write(` <!DOCTYPE html> <html> <head> <title>Child window</title> </head> <body> </body> </html> `); // 关闭文档流,触发加载流程 win.document.close(); // 绑定onload事件 win.onload = () => { console.info('Child window loaded'); win.document.body.style.background = 'hotpink'; }; } document.addEventListener('DOMContentLoaded', () => { document.getElementById('open').addEventListener('click', openWindow); })
方式二:子窗口内嵌加载逻辑(修正版)
const openWindow = () => { const win = window.open('', '_blank', 'top=20, left=20, width=200, height=200'); win.document.write(` <!DOCTYPE html> <html> <head> <title>Child window</title> <script> const handleOnLoad = () => { console.info('Child window loaded'); document.body.style.background = 'hotpink'; } </script> </head> <body onload="handleOnLoad()"> </body> </html> `); win.document.close(); } document.addEventListener('DOMContentLoaded', () => { document.getElementById('open').addEventListener('click', openWindow); })
额外注意
子窗口的控制台日志会输出在子窗口的控制台中,而非父窗口,需切换到子窗口查看日志。
内容的提问来源于stack exchange,提问作者user3056783
相关产品推荐
相关产品推荐

