66

少し前に解決策を見つけたと思いました(私のブログを参照してください):

JavaScript (または JScript の場合) のエラー「解放されたスクリプトからコードを実行できません」が発生した場合は、head 内のメタ タグをスクリプト タグの前に移動してみてください。

...しかし、最新のブログ コメントの 1 つに基づいて、私が提案した修正がすべての人に有効であるとは限りません。これは、StackOverflow コミュニティに門戸を開くのに適していると思いました....

「解放されたスクリプトからコードを実行できません」というエラーの原因と解決策/回避策は何ですか?

4

12 に答える 12

36

存在しないウィンドウまたはフレームで作成された関数を呼び出すと、このエラーが発生します。

ウィンドウがまだ存在するかどうか事前にわからない場合は、それを検出するために try/catch を実行できます。

try
{
  f();
}
catch(e)
{
  if (e.number == -2146823277)
    // f is no longer available
    ...
}
于 2008-09-17T15:12:56.603 に答える
20

このエラーは、スクリプトの「親」ウィンドウが破棄された (つまり、閉じられた) 場合に発生しますが、(別のウィンドウなどで) まだ保持されているスクリプトへの参照が呼び出されます。「オブジェクト」はまだ生きていますが、実行したいコンテキストは生きていません。

やや汚れていますが、私の 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。

于 2009-09-01T05:35:05.217 に答える
8

これは私がこの振る舞いを見た非常に特殊なケースです。IE6とIE7で再現可能です。

iframe内から:

window.parent.mySpecialHandler = function() { ...work... }

次に、iframeを新しいコンテンツでリロードした後、iframeを含むウィンドウで次の操作を行います。

window.mySpecialHandler();

mySpecialHandlerが終了しないコンテキスト(iframeの元のDOM)で定義されているため、この呼び出しは「解放されたスクリプトからコードを実行できません」で失敗します。(iframeをリロードすると、このコンテキストが破壊されました。)

ただし、親ウィンドウで「シリアル化可能な」値(プリミティブ、関数を直接参照しないオブジェクトグラフ)を安全に設定できます。リモートウィンドウに作業を指定するために別のウィンドウ(私の場合はiframe)が本当に必要な場合は、作業を文字列として渡し、レシーバーで「評価」することができます。これには注意してください。通常、クリーンで安全な実装にはなりません。

于 2010-05-10T22:50:25.907 に答える
8

JS オブジェクトにアクセスしようとしている場合、最も簡単な方法はコピーを作成することです。

var objectCopy = JSON.parse(JSON.stringify(object));

それが役立つことを願っています。

于 2014-02-25T16:32:31.883 に答える
7

このエラーは、子ウィンドウが開いていない親ウィンドウと通信しようとすると、MSIE で発生する可能性があります。

(正確には、世界で最も役立つエラー メッセージ テキストではありません。)

于 2008-09-17T14:02:32.950 に答える
5

IE9 以降、別のオブジェクト内の配列に格納された Date オブジェクトで .getTime() を呼び出すと、このエラーが発生するようになりました。解決策は、Date メソッドを呼び出す前に Date であることを確認することでした。

失敗:rowTime = wl.rowData[a][12].getTime()

合格:rowTime = new Date(wl.rowData[a][12]).getTime()

于 2011-07-12T17:53:28.487 に答える
2

子フレーム内で最上位ウィンドウに参照型を追加し、子ウィンドウがリロードされた後にそれにアクセスしようとしたときに、この問題に遭遇しました

すなわち

// 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());
于 2013-05-30T19:19:12.650 に答える
1

これは実際には答えではありませんが、これが正確に発生する場所の例です。

フレーム A とフレーム B があります (これは私の考えではありませんが、それについて考えなければなりません)。フレーム A は変化せず、フレーム B は常に変化します。コードの変更をフレーム A に直接適用することはできないため、(ベンダーの指示に従って) フレーム B でのみ JavaScript を実行できます。これは、変化し続ける正確なフレームです。

5 秒ごとに実行する必要がある JavaScript があるため、フレーム B の JavaScript は新しいスクリプト タグを作成し、フレーム B のヘッド セクションに挿入します。呼び出す関数と同様に。注入された JavaScript は技術的にはフレーム A によって読み込まれますが (script タグが含まれているため)、フレーム B が変更されると、関数は setInterval によってアクセスできなくなります。

于 2012-04-29T03:26:42.833 に答える
0

ダイアログを開いているときに DHTMLX でこのエラーが発生しました & 親 ID または現在のウィンドウ ID が見つかりません

        $(document).ready(function () {

            if (parent.dxWindowMngr == undefined) return;
            DhtmlxJS.GetCurrentWindow('wnManageConDlg').show();

});

ダイアログを開くときに、正しい現在/親ウィンドウ ID を送信していることを確認してください。

于 2015-05-14T05:39:26.447 に答える
0

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 内にあります。

于 2017-06-13T09:50:29.813 に答える