我们假设您有两个框架,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更好地处理它,等等。这只是一个测试。)
答案 0 :(得分:1)
我不知道如何检查执行上下文是否消失,但我遇到的两个解决方法是:
将回调调用放入try / catch并忽略任何异常。
在与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();
或类似。