web-dev-qa-db-ja.com

iframeでJavaScript関数を呼び出す

親ページからiframeでJavaScript関数を呼び出す際に問題があります。これが私の2つのページです。

mainPage.html

<html>
<head>
    <title>MainPage</title>
    <script type="text/javascript">
        function Reset() 
        {
            if (document.all.resultFrame)
                alert("resultFrame found");
            else
                alert("resultFrame NOT found");

            if (typeof (document.all.resultFrame.Reset) == "function")
                document.all.resultFrame.Reset();
            else
                alert("resultFrame.Reset NOT found");
        }
    </script>
</head>
<body>
    MainPage<br>
    <input type="button" onclick="Reset()" value="Reset"><br><br>
    <iframe height="100" id="resultFrame" src="resultFrame.html"></iframe>
</body>
</html>

resultFrame.html

<html>
<head>
    <title>ResultPage</title>
    <script type="text/javascript">
        function Reset() 
        {
            alert("reset (in resultframe)");
        }
    </script>
</head>
<body>
    ResultPage
</body>
</html>

(そんなこと知ってる document.allは推奨されませんが、このページはIE内部でのみ表示されるべきであり、それが問題だとは思わない)

リセットボタンを押すと、「resultFrame found」と「resultFrame.Reset NOT found」が表示されます。フレームへの参照があるように見えますが、フレームで関数を呼び出すことができません。なぜですか?

55
salle55

つかいます:

_document.getElementById("resultFrame").contentWindow.Reset();
_

iframeのリセット機能にアクセスするには

document.getElementById("resultFrame")はコード内のiframeを取得し、contentWindowはiframe内のウィンドウオブジェクトを取得します。子ウィンドウを取得したら、そのコンテキストでjavascriptを参照できます。

[〜#〜] here [〜#〜] 特にbobinceからの回答も参照してください。

106

文書からフレームを取得する代わりに、ウィンドウオブジェクトからフレームを取得してみてください。

上記の例ではこれを変更します:

if (typeof (document.all.resultFrame.Reset) == "function")
    document.all.resultFrame.Reset();
else
    alert("resultFrame.Reset NOT found");

if (typeof (window.frames[0].Reset) == "function")
    window.frames[0].Reset();
else
    alert("resultFrame.Reset NOT found");

問題は、iframe内のjavascriptのスコープがiframeのDOM要素を介して公開されていないことです。ウィンドウオブジェクトのみが、フレームのJavaScriptスコーピング情報を含んでいます。

5
barkmadley

さらに堅牢にするために:

function getIframeWindow(iframe_object) {
  var doc;

  if (iframe_object.contentWindow) {
    return iframe_object.contentWindow;
  }

  if (iframe_object.window) {
    return iframe_object.window;
  } 

  if (!doc && iframe_object.contentDocument) {
    doc = iframe_object.contentDocument;
  } 

  if (!doc && iframe_object.document) {
    doc = iframe_object.document;
  }

  if (doc && doc.defaultView) {
   return doc.defaultView;
  }

  if (doc && doc.parentWindow) {
    return doc.parentWindow;
  }

  return undefined;
}

そして

...
var el = document.getElementById('targetFrame');

var frame_win = getIframeWindow(el);

if (frame_win) {
  frame_win.reset();
  ...
}
...
5

コール

window.frames['resultFrame'].Reset();
4
Arsen Mkrtchyan

objectframe.contentWindow.Reset()最初にフレーム内の最上位要素への参照が必要です。

3
Alex H

最初に満たす必要のある条件は、親とiframeの両方が同じOriginに属していることです。それが完了すると、子はwindow.openerメソッドを使用して親を呼び出すことができ、親は上記のように子に対して同じことを行うことができます

2

Document.allを介してresultFrameにアクセスすると、ウィンドウフレームではなくHTML要素としてのみプルされます。 「this」自己参照を使用してイベントを発生させるフレームがある場合、同じ問題が発生します。

交換:

document.all.resultFrame.Reset();

と:

window.frames.resultFrame.Reset();

または:

document.all.resultFrame.contentWindow.Reset();
1

直接使用できず、このエラーが発生した場合:Origin " http:// www .. com"のフレームがクロスオリジンフレームにアクセスできないようにブロックしました。関数を直接使用する代わりに postMessage() を使用できます。

0
user9384187