【问题标题】:Calling javascript function in iframe在 iframe 中调用 javascript 函数
【发布时间】:2022-01-02 12:29:25
【问题描述】:

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

ma​​inPage.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”。好像有frame的引用但是不能调用frame上的函数,这是为什么呢?

【问题讨论】:

标签: javascript function iframe


【解决方案1】:

用途:

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

访问 iframe 中的重置功能

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

另请参阅HERE,尤其是 bobince 的回答。

【讨论】:

  • 嗨乔纳森,.contentWindow 还可以工作吗?我做了console.log(document.getElementById('iframeID').contentWindow) 并且在Firebug 中它在我的iframe 中正确显示了我的test() 函数,但是当我调用该函数时它说它不是函数,但它是!在 FF4 中进行测试。
【解决方案2】:

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

【讨论】:

    【解决方案3】:

    打电话

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

    【讨论】:

      【解决方案4】:

      当您通过 document.all 访问 resultFrame 时,它​​只会将其作为 HTML 元素拉取,而不是窗口框架。如果你有一个使用“this”自引用的框架触发一个事件,你会遇到同样的问题。

      替换:

      document.all.resultFrame.Reset();
      

      与:

      window.frames.resultFrame.Reset();
      

      或者:

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

      【讨论】:

        【解决方案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 范围信息。

        【讨论】:

          【解决方案6】:

          为了更加稳健:

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

          【讨论】:

            【解决方案7】:

            需要满足的首要条件是父框架和 iframe 都应该属于同一个来源。完成后,孩子可以使用 window.opener 方法调用父母,父母可以为孩子做同样的事情,如上所述

            【讨论】:

              【解决方案8】:

              如果不能直接使用,遇到这个错误: 阻止来源为“http://www..com”的框架访问跨域框架。 您可以使用postMessage(),而不是直接使用该函数。

              【讨论】:

                【解决方案9】:

                &lt;iframe&gt; 调用尊重隐私的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);
                

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2015-03-18
                  • 2011-07-05
                  • 1970-01-01
                  • 2013-10-24
                  相关资源
                  最近更新 更多