我以为我不久前找到了解决方案(请参阅我的博客):
如果您遇到 JavaScript(或者应该是 JScript)错误“无法从释放的脚本执行代码” - 尝试移动头部中的任何元标记,使它们位于您的脚本标记之前。
...但根据最近的一篇博客评论,我建议的修复方法可能并不适用于所有人。我认为这是向 StackOverflow 社区开放的好方法....
是什么导致错误“无法从释放的脚本执行代码”以及解决方案/变通方法是什么?
我以为我不久前找到了解决方案(请参阅我的博客):
如果您遇到 JavaScript(或者应该是 JScript)错误“无法从释放的脚本执行代码” - 尝试移动头部中的任何元标记,使它们位于您的脚本标记之前。
...但根据最近的一篇博客评论,我建议的修复方法可能并不适用于所有人。我认为这是向 StackOverflow 社区开放的好方法....
是什么导致错误“无法从释放的脚本执行代码”以及解决方案/变通方法是什么?
当您调用在不再存在的窗口或框架中创建的函数时,您会收到此错误。
如果您事先不知道窗口是否仍然存在,您可以执行 try/catch 来检测它:
try
{
f();
}
catch(e)
{
if (e.number == -2146823277)
// f is no longer available
...
}
当脚本的“父”窗口被释放(即:关闭)但对仍然保留的脚本的引用(例如在另一个窗口中)被调用时,会导致错误。即使“对象”还活着,但它想要执行的上下文不是。
它有点脏,但它适用于我的 Windows 边栏小工具:
这是一般的想法:“主”窗口设置一个函数来评估一些代码,是的,它就是丑陋的。然后“子”可以调用这个“构建器函数”(它/绑定到主窗口的范围/)并取回一个也绑定到“主”窗口的函数。当然,一个明显的缺点是,被“反弹”的函数不能在它看似定义的范围内关闭......无论如何,足够的胡言乱语:
这是部分伪代码,但我在 Windows 侧边栏小工具上使用了它的一个变体(我一直这么说是因为侧边栏小工具在“不受限制的区域 0”中运行,这可能会——也可能不会——极大地改变场景。)
// This has to be setup from the main window, not a child/etc!
mainWindow.functionBuilder = function (func, args) {
// trim the name, if any
var funcStr = ("" + func).replace(/^function\s+[^\s(]+\s*\(/, "function (")
try {
var rebuilt
eval("rebuilt = (" + funcStr + ")")
return rebuilt(args)
} catch (e) {
alert("oops! " + e.message)
}
}
// then in the child, as an example
// as stated above, even though function (args) looks like it's
// a closure in the child scope, IT IS NOT. There you go :)
var x = {blerg: 2}
functionInMainWindowContenxt = mainWindow.functionBuilder(function (args) {
// in here args is in the bound scope -- have at the child objects! :-/
function fn (blah) {
return blah * args.blerg
}
return fn
}, x)
x.blerg = 7
functionInMainWindowContext(6) // -> 42 if I did my math right
作为一个变体,主窗口应该能够将 functionBuilder 函数传递给子窗口——只要 functionBuilder 函数是在主窗口上下文中定义的!
我觉得我用了太多的词。天啊。
这是一个非常具体的案例,我在其中看到了这种行为。它在 IE6 和 IE7 中对我来说是可重现的。
从 iframe 中:
window.parent.mySpecialHandler = function() { ...work... }
然后,在使用新内容重新加载 iframe 后,在包含 iframe 的窗口中:
window.mySpecialHandler();
此调用因“无法从释放的脚本执行代码”而失败,因为 mySpecialHandler 是在不再存在的上下文(iframe 的原始 DOM)中定义的。(重新加载 iframe 破坏了这个上下文。)
但是,您可以在父窗口中安全地设置“可序列化”值(原语、不直接引用函数的对象图)。如果你真的需要一个单独的窗口(在我的例子中是一个 iframe)来向远程窗口指定一些工作,你可以将工作作为字符串传递并在接收器中“评估”它。小心这一点,它通常不会带来干净或安全的实现。
如果您尝试访问 JS 对象,最简单的方法是创建一个副本:
var objectCopy = JSON.parse(JSON.stringify(object));
希望它会有所帮助。
当子窗口尝试与不再打开的父窗口通信时,MSIE 中可能会发生此错误。
(不完全是世界上最有用的错误消息文本。)