使用window.open返回值修改子窗口DOM后变更消失,如何解决?
父窗口修改子窗口DOM属性后修改消失的解决问题
我有一个可在同域名下打开新窗口的网页,需要让父窗口修改子窗口的DOM属性。使用window.opener可以正常实现,但在TypeScript中这种方式存在类型不安全的问题。
我尝试改用window.open()的返回值来实现,然而对子窗口做出的修改仅会短暂显示后就消失。此场景仅涉及浏览器端JavaScript,无服务器端逻辑。
可行方案:使用window.opener
该方案可正常工作,但在TypeScript中不安全。无需Web服务器,可通过file:// URL在浏览器中打开。
first.html
<!DOCTYPE html> <html> <head> <title>First window - using window.opener</title> </head> <body> <script> // 这个全局函数由子窗口调用 function onSecondWindowReady(paragraphElement) { document.body.append(`Received a ${paragraphElement.constructor.name} from the second window.`); paragraphElement.style.background = "yellow"; paragraphElement.innerText += " It should be yellow now." } document.addEventListener("DOMContentLoaded", () => { const secondWindow = window.open("second.html", "secondWindow"); if (!secondWindow) { document.body.append("Second window didn't open, please check web browser popup blocker."); } }); </script> <p>This is the first window.</p> </body> </html>
second.html
<!DOCTYPE html> <html> <head> <title>Second window - using window.opener</title> </head> <body> <script> document.addEventListener("DOMContentLoaded", () => { window.opener.onSecondWindowReady(document.querySelector("p")); }); </script> <p>This is the second window.</p> </body> </html>
预期结果
- 父窗口中添加文本“Received a HTMLParagraphElement from the second window”;
- 子窗口中文本变为“This is the second window. It should be yellow now”且背景为黄色。
不可行方案:使用window.open()返回值
此方案需使用Web服务器,若通过file:// URL打开会触发跨域DOMException。可使用VS Code的Live Server等静态文件服务器。
first.html
<!DOCTYPE html> <html> <head> <title>First window - using window.open() return value</title> </head> <body> <script> document.addEventListener("DOMContentLoaded", () => { const firstWindow = window; const secondWindow = window.open("second.html", "secondWindow"); if (secondWindow) { function accessTheSecondWindow() { const paragraphElementInSecondWindow = secondWindow.document.querySelector("p"); if (paragraphElementInSecondWindow) { firstWindow.document.body.append(`Found a <p> in the second window.`); paragraphElementInSecondWindow.style.background = "yellow"; paragraphElementInSecondWindow.innerText += " It should be yellow now."; } else { // 有时因开发服务器缓存或热重载导致 firstWindow.document.body.append("Couldn't find a <p> element in the second window, please reload this page."); } } if (secondWindow.document.readyState === "complete") { firstWindow.document.body.append("The second window already finished loading. "); accessTheSecondWindow(); } else { firstWindow.document.body.append("The second window is still loading, adding event listener. "); secondWindow.document.addEventListener("DOMContentLoaded", () => { firstWindow.document.body.append("DOMContentLoaded event fired in second window. "); accessTheSecondWindow(); }); } } else { document.body.append("Second window didn't open, please check web browser popup blocker."); } }); </script> <p>This is the first window.</p> </body> </html>
second.html
<!DOCTYPE html> <html> <head> <title>Second window - using window.open() return value</title> </head> <body> <p>This is the second window.</p> </body> </html>
预期结果
与上述可行方案一致。
实际结果
- 父窗口中添加文本“Found a
in the second window.”;
- 子窗口中“ It should be yellow now”文本及黄色背景仅短暂显示后消失;
- 刷新父窗口会重复上述现象;
- 已在Windows系统的Firefox和Chrome浏览器(禁用扩展)中测试。
如何让对子窗口的修改持久保留?
内容的提问来源于stack exchange,提问作者Peter F
相关产品推荐
相关产品推荐

