
本文介绍在跨域受限环境下,使用 `document.readystate === 'complete'` 配合轮询机制可靠检测 `window.open()` 打开的子窗口加载完成的方法,并提供可直接运行的完整示例与关键注意事项。
在 Web 开发中,通过 window.open() 创建新窗口后,常需在其 DOM 就绪或资源完全加载后执行操作(如修改样式、注入脚本、通信等)。但直接监听 DOMContentLoaded 或 load 事件往往失败——根本原因在于:当 window.open('') 打开一个空窗口(about:blank)时,其 document 对象虽已存在,但事件监听器无法正确绑定到尚未完全初始化的跨上下文文档中;更关键的是,若目标页面与父页不同源(如打开外部 URL),浏览器会因同源策略禁止访问子窗口的 document 和事件系统,导致所有基于事件的方案失效。
因此,最兼容、最可靠的方案是采用 document.readyState 轮询法:
- document.readyState 有三个值:'loading'、'interactive'、'complete';
- 'complete' 表示文档及所有依赖资源(CSS、图片、子框架等)均已加载完毕,等效于 window.onload 触发时机;
- 对新开的 about:blank 窗口,该属性可安全读取(同源前提下),且无需事件绑定。
以下为经过验证的完整实现:
Opening window with JS
✅ 关键要点说明:
- 必须加 try...catch:当子窗口加载的是跨域页面(如 https://example.com)时,访问 win.document 会立即抛出 SecurityError,不捕获将导致脚本中断;
- 检查 win.closed:防止轮询期间用户手动关闭窗口,避免内存泄漏或错误操作;
- 轮询间隔建议 50–200ms:过短增加 CPU 负担,过长影响响应及时性;
- 仅适用于同源场景的深度控制:若需与跨域子页通信,请改用 postMessage() + message 事件(需子页主动配合);
- 不推荐 document.write() 方案:它会覆盖整个文档、重置状态,且现代浏览器中易触发 CSP 限制,可维护性差。
总结:readyState === 'complete' 轮询是当前最稳定、无依赖、广泛兼容的子窗口加载检测方式。它绕过了事件绑定的不确定性,直击加载完成的本质状态,是生产环境值得信赖的选择。











