私はしばらく前に解決策を見つけたと思った(私の ブログ を参照):
JavaScript(またはJScriptである必要があります)エラー "解放されたスクリプトからコードを実行できません"を取得した場合-メタタグを移動して、スクリプトタグの前に配置してください。
...しかし、最近のブログのコメントの1つに基づいて、私が提案した修正はすべての人に有効ではないかもしれません。これは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関数を子ウィンドウに渡すことができる必要があります!
言葉を使いすぎたように感じます。 YMMV。
JSオブジェクトにアクセスしようとしている場合、最も簡単な方法はコピーを作成することです。
var objectCopy = JSON.parse(JSON.stringify(object));
それが役立つことを願っています。
このエラーは、子ウィンドウが開いていない親ウィンドウと通信しようとしたときにMSIEで発生する可能性があります。
(正確に世界で最も役立つエラーメッセージテキストではありません。)
この動作を確認した非常に特殊なケースを次に示します。 IE6とIE7で再現可能です。
Iframe内から:
window.parent.mySpecialHandler = function() { ...work... }
次に、iframeを含むウィンドウで、新しいコンテンツでiframeをリロードした後:
window.mySpecialHandler();
MySpecialHandlerが終了したコンテキスト(iframeの元のDOM)で定義されていたため、この呼び出しは「解放されたスクリプトからコードを実行できません」で失敗します。 (iframeをリロードすると、このコンテキストが破壊されました。)
ただし、親ウィンドウで「シリアライズ可能な」値(プリミティブ、関数を直接参照しないオブジェクトグラフ)を安全に設定できます。リモートウィンドウに作業を指定するために別のウィンドウ(私の場合はiframe)が本当に必要な場合は、その作業を文字列として渡し、受信機で「評価」することができます。これには注意してください。通常、クリーンまたは安全な実装にはなりません。
IE9以降、別のオブジェクト内の配列に保存されているDateオブジェクトで.getTime()を呼び出すと、このエラーが発生し始めました。解決策は、Dateメソッドを呼び出す前に、それがDateであることを確認することでした:
失敗:rowTime = wl.rowData[a][12].getTime()
パス:rowTime = new Date(wl.rowData[a][12]).getTime()
子フレームの内部で参照タイプをトップレベルウィンドウに追加し、子ウィンドウがリロードした後にアクセスしようとしたときに、この問題に遭遇しました
つまり.
// set the value on first load
window.top.timestamp = new Date();
// after frame reloads, try to access the value
if(window.top.timestamp) // <--- Raises exception
...
プリミティブ型のみを使用して問題を解決できました
// set the value on first load
window.top.timestamp = Number(new Date());
これは実際には答えではありませんが、これが正確に起こる場所の例です。
フレームAとフレームBがあります(これは私の考えではありませんでしたが、一緒に生きなければなりません)。フレームAは決して変化せず、フレームBは常に変化します。コードの変更をフレームAに直接適用することはできないため、ベンダーの指示に従って、フレームBでのみJavaScriptを実行できます。フレームBは、変化を続けるフレームそのものです。
5秒ごとに実行する必要があるJavaScriptがあるため、フレームBのJavaScriptは新しいスクリプトタグを作成し、フレームBのヘッドセクションに挿入します。呼び出す関数も同様です。挿入されたJavaScriptはフレームAによって技術的に読み込まれますが(スクリプトタグが含まれているため)、フレームBが変更されると、関数はsetIntervalでアクセスできなくなります。
最終的にiFrameを開くページ内でIE9でこのエラーが発生しました。 iFrameが開いていない限り、localStorageを使用できます。 iFrameを開いて閉じた後、このエラーのためにlocalStorageを使用できなくなりました。それを修正するには、iFrame内のlocalscriptを使用するJavascriptにこのコードを追加する必要がありました。
if (window.parent) {
localStorage = window.parent.localStorage;
}
Iframeのsrcを更新すると、そのエラーが発生します。
次のようなメインウィンドウの要素のイベント(私の場合はクリック)にアクセスして(メイン/一番外側のウィンドウを直接呼び出して)エラーを取得しました。
top.$("#settings").on("click",function(){
$("#settings_modal").modal("show");
});
私はこれをこのように変更しただけで正常に動作します(iframeウィンドウの親の親を呼び出す):
$('#settings', window.parent.parent.document).on("click",function(){
$("#settings_modal").modal("show");
});
モーダルを含む私のiframeも別のiframe内にあります。
説明は、前の回答に非常に関連しています。私のシナリオを提供しようとしています。これが他の人に役立つことを願っています。
私たちは使用していました:
<script> window.document.writeln(table) </script>
、およびonchange
イベントでスクリプト内の他の関数を呼び出しますが、writelnは、IEのHTMLを完全にオーバーライドします。
次のように変更しました:
<script> window.document.body.innerHTML = table;</script>
したがって、問題を修正したスクリプトを保持しました。
ダイアログを開いているときにDHTMLXでこのエラーが発生し、親IDまたは現在のウィンドウIDが見つかりません
$(document).ready(function () {
if (parent.dxWindowMngr == undefined) return;
DhtmlxJS.GetCurrentWindow('wnManageConDlg').show();
});
ダイアログを開くときに正しい通貨/親ウィンドウIDを送信していることを確認してください