在iframe中调用javascript函数

时间:2009-10-21 12:30:03

标签: javascript iframe

我在从父页面调用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>

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”和“找不到resultFrame.Reset”。它似乎有一个框架的引用但不能调用框架上的函数,为什么会这样?

9 个答案:

答案 0 :(得分:98)

使用:

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

访问iframe中的重置功能

document.getElementById("resultFrame") 将在您的代码中获取iframe,contentWindow将获取iframe中的窗口对象。拥有子窗口后,您可以在该上下文中引用javascript。

另请参阅HERE特别是bobince的答案。

答案 1 :(得分:5)

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

在上面的例子中改变了这个:

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范围信息。

答案 2 :(得分:5)

更强大:

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

答案 3 :(得分:4)

呼叫

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

答案 4 :(得分:3)

objectframe.contentWindow.Reset()您首先需要引用框架中的顶级元素。

答案 5 :(得分:2)

需要满足的第一个也是最重要的条件是父和iframe都属于同一个来源。一旦完成,子进程可以使用window.opener方法调用父进程,父进程可以为上面提到的子进行相同的操作

答案 6 :(得分:1)

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

替换:

document.all.resultFrame.Reset();

使用:

window.frames.resultFrame.Reset();

或者:

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

答案 7 :(得分:0)

如果您无法直接使用它并且遇到此错误: 阻止具有原点“http://www .. com”的帧访问跨源帧。 您可以使用postMessage()而不是直接使用该功能。

答案 8 :(得分:0)

XMLHttpRequest 调用尊重隐私的 <iframe>

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);
相关问题