【问题标题】:What’s the best way to reload / refresh an iframe?重新加载/刷新 iframe 的最佳方式是什么?
【发布时间】:2021-08-02 23:48:03
【问题描述】:

我想使用 JavaScript 重新加载 <iframe>。到目前为止,我发现的最好方法是将 iframe 的 src 属性设置为自身,但这不是很干净。有什么想法吗?

【问题讨论】:

  • src 属性设置为自身不干净是有原因的吗?它似乎是唯一适用于跨浏览器和跨域的解决方案
  • 如果您在其他地方有指向<iframe> 的链接,则将src 属性设置为自身会导致问题。然后框架将显示最初设计的初始页面。
  • 设置 src 属性会将 iframe 滚动到页面顶部,而 location.reload() 不会。如果您正在重新加载,例如iframe 底层的 CSS 已经改变,后者会更好。

标签: javascript iframe


【解决方案1】:
document.getElementById('some_frame_id').contentWindow.location.reload();

注意,在 Firefox 中,window.frames[] 不能按 id 索引,而是按名称或索引

【讨论】:

  • 实际上,这种方法在 Chrome 中对我不起作用。没有“contentWindow”属性。虽然可以使用 document.getElementById('some_frame_id').location.reload();适用于 FF 和 Chrome 的方法是 document.getElementById('iframeid').src = document.getElementById('iframeid').src
  • @MikeBevz 可以使用 Jquery 选择器访问 location.reload 吗?
  • 绝对可行,但坚持同域来源策略 ==a
  • frames[1].location.href.reload()window.frames['some_frame_id'].location.href.reload()也可以用
  • 如果无法访问 iframe 窗口,则必须更改 iframe 标签的 src 属性。
【解决方案2】:
document.getElementById('iframeid').src = document.getElementById('iframeid').src

它会重新加载iframe,甚至跨域! 通过 IE7/8、Firefox 和 Chrome 测试。

【讨论】:

  • document.getElementById('iframeid').src += ''; 也可以:jsfiddle.net/Daniel_Hug/dWm5k
  • 如果 iframe 的源在添加到页面后发生了更改,您该怎么办?
  • 在 Chrome ver33 上为我工作!奇怪的是我们不能简单地使用reload,但这是允许的。
  • 请注意,如果 iframe src 中包含哈希(例如 http://example.com/#something),则不会重新加载框架。我使用了在哈希之前的 URL 中添加一个一次性查询参数(如 ?v2)的方法。
  • 这会导致 iframe 滚动回顶部。
【解决方案3】:

如果使用 jQuery,这似乎可行:

$('#your_iframe').attr('src', $('#your_iframe').attr('src'));

【讨论】:

  • 这个,没有 jQuery:var iframe = document.getElementById("your_iframe"); iframe.src = src;
  • 请注意,这个(以及纯 js 解决方案)是最好用的,因为它是跨平台的并且可以跨域工作。
  • @Seagrass 我想你的意思是:var iframe = document.getElementById("your_iframe"); iframe.src = iframe.src;
【解决方案4】:

添加空白空间也会自动重新加载 iFrame。

document.getElementById('id').src += '';

【讨论】:

  • 这是最好的答案,因为它适用于所有 iframe,包括跨域 iframe。相比之下,contentWindow.location.reload() 方法仅适用于来自同一来源的 iframe。
  • 但是后者不会滚动到顶部,所以这取决于你的优先级。
【解决方案5】:
window.frames['frameNameOrIndex'].location.reload();

【讨论】:

    【解决方案6】:

    由于same origin policy,这在修改指向不同域的 iframe 时不起作用。如果您可以针对较新的浏览器,请考虑使用HTML5's Cross-document messaging。您可以在此处查看支持此功能的浏览器:http://caniuse.com/#feat=x-doc-messaging

    如果您不能使用 HTML5 功能,那么您可以遵循此处列出的技巧:http://softwareas.com/cross-domain-communication-with-iframes。该博客条目也很好地定义了问题。

    【讨论】:

      【解决方案7】:

      我刚刚在 chrome 中遇到了这个问题,唯一可行的方法是删除和替换 iframe。示例:

      $(".iframe_wrapper").find("iframe").remove();
      var iframe = $('<iframe src="' + src + '" frameborder="0"></iframe>');
      $.find(".iframe_wrapper").append(iframe);
      

      很简单,其他答案中没有介绍。

      【讨论】:

        【解决方案8】:

        在我的情况下,仅替换 iframe 元素的 src 属性并不令人满意,因为在加载新页面之前会看到旧内容。如果您想提供即时视觉反馈,这会更好:

        var url = iframeEl.src;
        iframeEl.src = 'about:blank';
        setTimeout(function() {
            iframeEl.src = url;
        }, 10);
        

        【讨论】:

        • 我刚刚测试了相同的方法,但没有 setTimeout - 它对我有用。实际上,只是 iframe.setAttribute('src', iframe.getAttribute('src'))
        【解决方案9】:

        新网址

        location.assign("http:google.com");
        

        assign() 方法加载一个新文档。

        重新加载

        location.reload();
        

        reload() 方法用于重新加载当前文档。

        【讨论】:

          【解决方案10】:

          对 yajra 帖子的改进...我喜欢这个想法,但讨厌浏览器检测的想法。

          我宁愿采取 ppk 的观点,即使用对象检测而不是浏览器检测, (http://www.quirksmode.org/js/support.html), 因为那时你实际上是在测试浏览器的功能并采取相应的行动,而不是你认为浏览器当时的能力。也不需要那么多难看的浏览器 ID 字符串解析,也不排除你一无所知的完美浏览器。

          那么,与其查看 navigator.AppName,不如做这样的事情,实际测试您使用的元素? (如果您想变得更漂亮,可以使用 try {} 块,但这对我有用。)

          function reload_message_frame() {
              var frame_id = 'live_message_frame';
              if(window.document.getElementById(frame_id).location ) {  
                  window.document.getElementById(frame_id).location.reload(true);
              } else if (window.document.getElementById(frame_id).contentWindow.location ) {
                  window.document.getElementById(frame_id).contentWindow.location.reload(true);
              } else if (window.document.getElementById(frame_id).src){
                  window.document.getElementById(frame_id).src = window.document.getElementById(frame_id).src;
              } else {
                  // fail condition, respond as appropriate, or do nothing
                  alert("Sorry, unable to reload that frame!");
              }
          }
          

          这样,您可以根据需要尝试尽可能多的不同排列,而不会导致 javascript 错误,并在所有其他方法都失败时做一些明智的事情。在使用对象之前测试您的对象需要做更多的工作,但是,IMO 可以生成更好、更安全的代码。

          在 Windows 上的 IE8、Firefox (15.0.1)、Chrome (21.0.1180.89 m) 和 Opera (12.0.2) 中为我工作。

          也许我可以通过实际测试重新加载功能做得更好,但这对我来说已经足够了。 :)

          【讨论】:

            【解决方案11】:

            另一种解决方案。

            const frame = document.getElementById("my-iframe");
            
            frame.parentNode.replaceChild(frame.cloneNode(), frame);
            

            【讨论】:

            • 这样做的一个缺点是修改了根文档 DOM 树并会导致重绘。我用var url = ifr.src; ifr.src = null; ifr.src = url;
            【解决方案12】:

            现在要在 chrome 66 上进行这项工作,试试这个:

            const reloadIframe = (iframeId) => {
                const el = document.getElementById(iframeId)
                const src = el.src
                el.src = ''
                setTimeout(() => {
                    el.src = src
                })
            }
            

            【讨论】:

              【解决方案13】:

              在使用.Net的IE8中,第一次设置iframe.src是可以的, 但是第二次设置iframe.src并没有提高iframed页面的page_load。 为了解决它,我使用了iframe.contentDocument.location.href = "NewUrl.htm"

              在使用 jQuery 厚框并尝试在厚框 iframe 中重新打开同一页面时发现它。 然后它只显示之前打开的页面。

              【讨论】:

                【解决方案14】:

                IE 使用 reload,其他浏览器设置 src。 (重新加载在 FF 上不起作用) 在 IE 7、8、9 和 Firefox 上测试

                if(navigator.appName == "Microsoft Internet Explorer"){
                    window.document.getElementById('iframeId').contentWindow.location.reload(true);
                }else {
                    window.document.getElementById('iframeId').src = window.document.getElementById('iframeId').src;
                }
                

                【讨论】:

                  【解决方案15】:

                  如果你使用 Jquery,那么只有一行代码。

                  $('#iframeID',window.parent.document).attr('src',$('#iframeID',window.parent.document).attr('src'));
                  

                  如果你和同一个父母一起工作,那么

                  $('#iframeID',parent.document).attr('src',$('#iframeID',parent.document).attr('src'));
                  

                  【讨论】:

                    【解决方案16】:

                    使用self.location.reload() 将重新加载 iframe。

                    <iframe src="https://vivekkumar11432.wordpress.com/" width="300" height="300"></iframe>
                    <br><br>
                    <input type='button' value="Reload"  onclick="self.location.reload();" />

                    【讨论】:

                    • 重新加载整个主窗口
                    • 这适用于当前 iFrame 中的 JavaScript。
                    【解决方案17】:

                    如果以上所有方法都不适合您:

                    window.location.reload();
                    

                    由于某种原因,这刷新了我的 iframe 而不是整个脚本。也许是因为它被放置在框架本身中,而当您尝试从另一个框架刷新框架时,所有这些 getElemntById 解决方案都可以工作?

                    或者我不完全理解这一点并且胡言乱语,无论如何这对我来说就像一个魅力:)

                    【讨论】:

                      【解决方案18】:

                      您是否考虑过在 url 上附加一个无意义的查询字符串参数?

                      <iframe src="myBaseURL.com/something/" />
                      
                      <script>
                      var i = document.getElementsById("iframe")[0],
                          src = i.src,
                          number = 1;
                      
                      //For an update
                      i.src = src + "?ignoreMe=" + number;
                      number++;
                      </script>
                      

                      它不会被看到,如果你知道参数是安全的,那么它应该没问题。

                      【讨论】:

                        【解决方案19】:
                        <script type="text/javascript">
                          top.frames['DetailFrame'].location = top.frames['DetailFrame'].location;
                        </script> 
                        

                        【讨论】:

                        • 不是我会使用的选择,但我想它会做。加上一些你可以添加的额外代码。
                        【解决方案20】:

                        如果您尝试了所有其他建议,但无法让其中任何一个发挥作用(就像我做不到一样),那么您可以尝试以下可能有用的方法。

                        HTML

                        <a class="refresh-this-frame" rel="#iframe-id-0">Refresh</a>
                        <iframe src="" id="iframe-id-0"></iframe>
                        

                        JS

                        $('.refresh-this-frame').click(function() {
                            var thisIframe = $(this).attr('rel');
                            var currentState = $(thisIframe).attr('src');
                            function removeSrc() {
                                $(thisIframe).attr('src', '');
                            }
                            setTimeout (removeSrc, 100);
                            function replaceSrc() {
                                $(thisIframe).attr('src', currentState);
                            }
                            setTimeout (replaceSrc, 200);
                        });
                        

                        我最初打算尝试通过 RWD 和跨浏览器测试来节省一些时间。我想创建一个包含一堆 iframe 的快速页面,这些 iframe 被组织成我可以随意显示/隐藏的组。从逻辑上讲,您希望能够轻松快速地刷新任何给定的帧。

                        我应该注意,我目前正在从事的项目,也就是在这个测试平台中使用的项目,是一个带有索引位置的单页站点(例如 index.html#home)。这可能与为什么我无法获得任何其他解决方案来刷新我的特定框架有关。

                        话虽如此,我知道这不是世界上最干净的东西,但它适用于我的目的。希望这可以帮助某人。现在,如果我能弄清楚每次 iframe 内有动画时如何防止 iframe 滚动父页面...

                        编辑: 我意识到这不会像我希望的那样“刷新” iframe。它会重新加载 iframe 的初始源。仍然无法弄清楚为什么我无法使用其他任何选项..

                        更新: 我无法让任何其他方法起作用的原因是因为我在 Chrome 中测试它们,如果它不是源自相同的位置(据我所知)。经过进一步测试,我也无法访问 FF 中的 contentWindow。

                        修改后的 JS

                        $('.refresh-this-frame').click(function() {
                            var targetID = $(this).attr('rel');
                            var targetSrc = $(targetID).attr('src');
                            var cleanID = targetID.replace("#","");     
                            var chromeTest = ( navigator.userAgent.match(/Chrome/g) ? true : false );
                            var FFTest = ( navigator.userAgent.match(/Firefox/g) ? true : false );      
                            if (chromeTest == true) {
                                function removeSrc() {
                                    $(targetID).attr('src', '');
                                }
                                setTimeout (removeSrc, 100);
                                function replaceSrc() {
                                    $(targetID).attr('src', targetSrc);
                                }
                                setTimeout (replaceSrc, 200);
                            }
                            if (FFTest == true) {
                                function removeSrc() {
                                    $(targetID).attr('src', '');
                                }
                                setTimeout (removeSrc, 100);
                                function replaceSrc() {
                                    $(targetID).attr('src', targetSrc);
                                }
                                setTimeout (replaceSrc, 200);
                            }       
                            if (chromeTest == false && FFTest == false) {
                                var targetLoc = (document.getElementById(cleanID).contentWindow.location).toString();
                                function removeSrc() {
                                    $(targetID).attr('src', '');
                                }
                                setTimeout (removeSrc, 100);
                                function replaceSrc2() {
                                    $(targetID).attr('src', targetLoc);
                                }
                                setTimeout (replaceSrc2, 200);
                            }
                        });
                        

                        【讨论】:

                          【解决方案21】:

                          出于调试目的,可以打开控制台,将执行上下文更改为他想要刷新的帧,然后执行document.location.reload()

                          【讨论】:

                            【解决方案22】:

                            从 Iframe 内部重新加载

                            如果您的应用位于 iframe 中,您可以通过替换位置 href 来刷新它:

                            document.location.href = document.location.href
                            

                            【讨论】:

                              猜你喜欢
                              • 1970-01-01
                              • 2012-03-02
                              • 2018-07-18
                              • 2016-03-15
                              • 2015-07-31
                              • 2017-12-13
                              • 2019-06-10
                              • 1970-01-01
                              相关资源
                              最近更新 更多