【问题标题】:Handle a callback when the calling frame (and execution context) has disappeared当调用框架(和执行上下文)消失时处理回调
【发布时间】:2011-08-17 22:55:57
【问题描述】:

假设您有两个框架,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 处理得更好等事实。这只是一个测试。)

【问题讨论】:

    标签: javascript callback scope frames


    【解决方案1】:

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

    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(); 或类似的。

    【讨论】:

    • 我现在有一个 try/catch 正在进行测试,但不确定它是否可以跨浏览器工作(有人说“IE”吗?)。目的绝对是不来更改 iframe src,这发生在外部。这只是为了模拟实际发生的情况。
    • 即使 try/catch 有效,我仍然想知道是否有任何方法可以正确处理此问题(当然,除了完全杀死帧,这是正确的解决方案)。
    • 仅供参考,try/catch 不起作用,因为 try/catch 本身在框架内。
    • 要回答您的其他问题,框架的内容是完全独立的(应该如此)。回调是一个 ajax 回调。因此,当 ajax 完成时,它会进入其源进行回调并发现......什么都没有!当然,页面对调用框架一无所知,也不应该。
    • 所以我现在又不知所措了。帮忙?
    猜你喜欢
    • 2019-07-31
    • 1970-01-01
    • 2018-03-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-26
    • 1970-01-01
    相关资源
    最近更新 更多