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

时间:2011-05-03 18:29:06

标签: javascript callback scope frames

我们假设您有两个框架,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.frameLoad。在回调运行之前,iframe src会更改为www.google.com,从而破坏回调的执行上下文。回调运行并产生错误。

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

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

1 个答案:

答案 0 :(得分:1)

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

  1. 将回调调用放入try / catch并忽略任何异常。

  2. 在与frameLoad功能相同的框架中定义回调功能,然后从iframe调用frameLoad将如下所示:top.frameLoad(top.someCallbackFunction);

    < / LI>

    如果您知道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();或类似。