親ページから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」が表示されます。フレームへの参照があるように見えますが、フレームで関数を呼び出すことができません。なぜですか?
つかいます:
_document.getElementById("resultFrame").contentWindow.Reset();
_
iframeのリセット機能にアクセスするには
document.getElementById("resultFrame")
はコード内のiframeを取得し、contentWindow
はiframe内のウィンドウオブジェクトを取得します。子ウィンドウを取得したら、そのコンテキストでjavascriptを参照できます。
[〜#〜] here [〜#〜] 特にbobinceからの回答も参照してください。
文書からフレームを取得する代わりに、ウィンドウオブジェクトからフレームを取得してみてください。
上記の例ではこれを変更します:
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スコーピング情報を含んでいます。
さらに堅牢にするために:
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();
...
}
...
コール
window.frames['resultFrame'].Reset();
objectframe.contentWindow.Reset()
最初にフレーム内の最上位要素への参照が必要です。
最初に満たす必要のある条件は、親とiframeの両方が同じOriginに属していることです。それが完了すると、子はwindow.openerメソッドを使用して親を呼び出すことができ、親は上記のように子に対して同じことを行うことができます
Document.allを介してresultFrameにアクセスすると、ウィンドウフレームではなくHTML要素としてのみプルされます。 「this」自己参照を使用してイベントを発生させるフレームがある場合、同じ問題が発生します。
交換:
document.all.resultFrame.Reset();
と:
window.frames.resultFrame.Reset();
または:
document.all.resultFrame.contentWindow.Reset();
直接使用できず、このエラーが発生した場合:Origin " http:// www .. com"のフレームがクロスオリジンフレームにアクセスできないようにブロックしました。関数を直接使用する代わりに postMessage() を使用できます。