在 iframe 中调用 javascript 函数

我在从父页面调用 iframe中的 JavaScript 函数时遇到了问题。以下是我的两个页面:

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>

Result tFrame.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 内部浏览,我不认为这是问题所在)

当我按 Reset-按钮时,我会得到“ result Frame found”和“ result Frame”。未找到重置”。它似乎有一个对框架的引用,但不能调用框架上的函数,这是为什么呢?

186414 次浏览

用途:

document.getElementById("resultFrame").contentWindow.Reset();

访问 iframe 中的 Reset 函数

document.getElementById("resultFrame") 将获取代码中的 iframe,而 contentWindow将获取 iframe 中的 window 对象。一旦有了子窗口,就可以在上下文中引用 javascript。

也特别看到 给你的答案从跳跃。

你首先需要引用框架中的顶层元素。

window.frames['resultFrame'].Reset();

当您通过 document.all 访问 Results tFrame 时,它只将其作为 HTML 元素,而不是窗口框架。如果使用“ this”自引用框架触发事件,也会出现同样的问题。

更换:

document.all.resultFrame.Reset();

配合:

window.frames.resultFrame.Reset();

或者:

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

尝试从窗口对象获取框架,而不是从文档中获取框架。

在上面的例子中改变这一点:

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();
...
}
...

需要满足的第一个也是最重要的条件是,父节点和 iframe 应该属于同一个源节点。一旦这样做了,子元素就可以使用 window.opener 方法调用父元素,而父元素也可以像上面提到的那样调用子元素

如果您不能直接使用它,并且遇到这个错误: 阻止原点为“ http://www.com”的帧访问跨原点的帧。 可以使用 PostMessage ()代替直接使用函数。

<iframe>呼叫尊重隐私的 XMLHttpRequest

HTML:

<iframe id="iframe"></iframe>

JavaScript:

const iframe    = document.getElementById('iframe');
const iframeWin = iframe.contentWindow || iframe;
const iframeDoc = iframe.contentDocument || iframeWin.document;


let script = iframeDoc.createElement('SCRIPT');


script.append(`function sendWithoutOrigin(url) {
let request = new XMLHttpRequest();


request.open('GET', url);


request.onreadystatechange = function() {
if(request.readyState === XMLHttpRequest.DONE) {
if(request.status === 200) {
console.log('GET succeeded.');
}
else {
console.warn('GET failed.');
}
}
}
request.send();
}`);


iframeDoc.documentElement.appendChild(script);

JavaScript 召唤:

let url  = 'https://api.serivce.net/';
url += '?api_key=' + api_write_key;
url += '&field1=' + value;


iframeWin.sendWithoutOrigin(url);