当调用框架(和执行上下文)消失时处理回调

Handle a callback when the calling frame (and execution context) has disappeared

本文关键字:消失 处理 回调 上下文 执行 调用 框架      更新时间:2023-09-26

让我们假设你有两个框架,A和B(或者一个带有iframe的页面)。A中有一个函数foo(),当它完成时,调用回调。B中的脚本从A调用foo(),但在它完成之前(并从B调用回调),B的src被完全替换,因此回调不再具有执行上下文。在大多数浏览器中,这会产生一些错误。

是否有任何方法可以检测回调来自不再具有执行上下文的运行时,因此不应该被调用?

换行页:

<html>
<head>
    <script>
        var load = function() {
            document.getElementById("link").onclick = function(){
                document.getElementById("iframe").src = "test-exec-context-frame-src.html";
                return(false);
            };
        };
        var frameLoad = function(cb) {
            // kill the frame and then callback
            document.getElementById("iframe").src = "http://www.google.com";
            cb();
        };
    </script>
</head>
<body onload="load();">
    <div>This is the first div, click <a id="link" href="#">here</a> to start</div>
    <iframe id="iframe"></iframe>
</body>

下面是iframe src页面:

<html>
<head>
    <script>
        var load2 = function() {
            document.getElementById("link").onclick = function(){
                top.frameLoad(function(){
                    console.log("I am done");
                });
            };
        };
    </script>
</head>
<body onload="load2();">
    <div>This is the internal frame. Click <a href="#" id="link">here</a> to force the callback.</div>
</body>

单击第一页中的链接,iframe将加载第二个源页面。点击第二页中的链接,它调用top. framload并带回调。在回调运行之前,iframe src被更改为www.google.com,从而破坏回调的执行上下文。回调函数运行并创建一个错误。

在尝试执行回调之前,我们如何检查回调(或者调用函数)的执行上下文?

(忽略格式化,全局变量的使用,jquery会比文档更好地处理它的事实。getElementById等等。这只是一个测试)

我不知道如何检查执行上下文是否消失,但我想到的两个变通方法是:

  1. 将回调调用放在try/catch中,忽略任何异常。

  2. 将回调函数定义在与frameLoad函数相同的帧中,因此从iframe中对frameLoad的调用将看起来像这样:top.frameLoad(top.someCallbackFunction);

如果你知道frameLoad函数的全部要点是替换定义回调的iframe的内容,那么为什么要使用回调呢?任何重要的回调都想要与原始内容交互,不是吗?您是否可以通过在最初位于iframe内的文档中定义onunload来实现类似的目标?

更新:

当我建议一个try/catch时,我的意思是在你的父文档脚本中像这样:

var frameLoad = function(cb) {
   // kill the frame and then callback
   document.getElementById("iframe").src = "http://www.google.com";
   try {
      cb();
   } catch(e) {
      // callback didn't work; do something if necessary
   }
}; 

您也可以尝试if (cb != undefined) cb();或类似的