掌握 window 对象方法的关键是理解权限模型:open() 需用户手势触发,否则被拦截;close() 仅限脚本打开且未跨域的窗口;focus()/blur() 在多标签/移动端效果受限;postMessage() 是唯一安全的跨窗口通信方式。
掌握 window 对象方法的关键,不是背全所有 API,而是清楚哪些能用、哪些已废弃、哪些在跨域或 iframe 场景下会静默失败。
现代浏览器默认拦截非用户手势触发的 window.open(),比如在 setTimeout 或 AJAX 回调里调用。
click、keydown)直接触发button.addEventListener('click', () => {
setTimeout(() => window.open('https://example.com'), 100); // ❌ 被拦截
});button.addEventListener('click', () => {
con
st win = window.open('https://example.com', '_blank');
if (!win || win.closed || typeof win.closed === 'undefined') {
alert('弹窗被拦截,请允许弹出窗口');
}
});window.open() 返回值可能是 null(被拦截)或一个受限的 Window 实例(跨域时无法读写 location、document)window.close() 只能关闭**脚本自己打开的窗口**(即通过 window.open() 创建且未导航到其他源的窗口),否则静默忽略。
window.close() 在多数浏览器中无效win.location.href = 'https://other-domain.com',再调用 win.close() 也可能失败(尤其跨域后)close() 调用focus() 并不总能让窗口获得焦点,尤其在多标签页环境或移动端;blur() 更是几乎无实际效果(浏览器普遍忽略)。
window.focus() 在 Chrome 中仅对当前 tab 有效,且需用户之前与该 tab 有过交互win.focus() 激活另一个 tab,大概率失败并抛出 DOMException: Blocked a frame with origin...
blur() 隐藏敏感内容——它不阻止用户切换回来,也不触发 visibilitychange
当需要和 window.open() 打开的窗口、iframe 或 target="_blank" 页面通信时,postMessage() 是唯一标准且受支持的方案。
'*'(除非你完全信任对方):popupWindow.postMessage({ type: 'AUTH_TOKEN', token: 'abc123' }, 'https://trusted.example.com');event.origin 和 event.source:window.addEventListener('message', (e) => {
if (e.origin !== 'https://trusted.example.com') return;
if (e.source !== popupWindow) return; // 确保来源可信
console.log(e.data);
});window.location、document、localStorage,一切数据交换都得靠 postMessage
真正难的不是调用这些方法,而是理解它们背后的权限模型:每个 Window 实例都运行在自己的上下文里,浏览器用同源策略和用户手势约束把它们隔开。绕不开这些限制,就容易写出看似正确却在真实环境中失效的代码。