如何从IFRAME内部触发'beforeunload'事件

12

我有一个应用程序(名为B),它由另一个主要应用程序(称为A或父级)通过Iframe嵌入。

So: App A--                     // domain of A: https://mydomain/mainApp
           |___ App B in Iframe // domain in B: https://mydomain/appB

问题是: 主/父应用程序有一个导航菜单。其中一个项目在被点击时,创建了一个使用SRC属性加载App B的Iframe。

当用户在应用程序A的菜单中点击另一个选项时,Iframe被销毁,React中的另一个内容视图出现,替换了Iframe。

这样做时,用户在B中键入的所有表单数据都会丢失,因为我无法触发B中的保存事件。

我已经在iframe应用程序中添加了以下事件处理程序:

window.addEventListener("beforeunload", function (e) {

    // Trigger here the save settigns event inside B
});

但是,当用户通过主应用程序菜单导航时,以前的代码永远不会触发。据我所见,在应用程序A中导航菜单会更改浏览器中的URL(但似乎是SPA React.js路由或类似的东西,没有真正的重定向)。

问题是:Iframe能否检测到即将被卸载/销毁以先触发Ajax中的保存设置?附言:我没有访问应用A的代码。

提前致谢

3个回答

12

来自MDN

WindowEventHandlers.onbeforeunload是一个事件处理属性,包含在发送beforeunload时执行的代码。当窗口即将卸载其资源时,会触发此事件。文档仍然可见,事件仍然可以取消。

unload事件在文档或子资源正在卸载时被触发。它在以下事件之后被触发:

  1. beforeunload(可取消事件)
  2. pagehide

示例:

<body>
    <input type="button" id="removeIframeBtn" value="remove iframe"/>
    <iframe id="iframe" src="http://localhost:8080/iframe.html"></iframe>
</body>

<script>
    const removeIframeBtn = document.getElementById("removeIframeBtn");
    const iframe = document.getElementById("iframe");

    iframe.contentWindow.onbeforeunload = function () {
        debugger;
    };

    window.onbeforeunload = function () {
        debugger;
    };

    removeIframeBtn.onclick = function () {
        iframe.remove();
    };
</script>

假设当前代码的页面已在浏览器选项卡中打开。
如果您试图关闭此选项卡,则将调用iframe.contentWindow.onbeforeunload
如果您尝试单击“删除iframe”按钮,则iframe将从文档中删除,但不会调用iframe.contentWindow.onbeforeunload。没有unload事件。
React使用js渲染组件,因此它与单击“删除iframe”按钮的第二种情况完全相同。
因此,对于您的问题的答案是:在单页应用程序中无法使用onbeforeunload事件检测iframe的卸载情况,因为它在路由更改时发生。
您的解决方案可以是在每次更改设置时保存设置。

0

卸载事件可以起到作用,因此您可以这样做

IframeWindow.addEventListener('unload', ()=>{
        debugger
      })

0

2023年8月:

unload(和pagehide)在父级删除一个iframe时被触发。在iframe内添加一个unload事件监听器,它将会被触发。然而,截至2023年8月,Firefox存在一个导致unload(和pagehide)无法触发的bug,所以我只能确认这在Chrome上是有效的(我没有测试过Safari - 请有Mac的人留言评论)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接