【问题标题】:How can I get Iframe event before load?如何在加载前获取 iframe 事件?
【发布时间】:2012-02-13 12:03:25
【问题描述】:

在我的网站中,我在 iframeB 中使用了 iframeA,并且当 iframeA 更改其内容时,我必须设置 src。我只能使用 onload 事件来设置它,但是在加载站点时会调用它。我正在寻找一些事件或触发器,它可以帮助我在开始加载之前检测位置/src 更改。我不想在 src 设置之前等待整个页面加载。我无法直接访问 iframeA(只有下面的脚本)

一些代码:

var myframe = document.getElementById('frameB').contentWindow.document.getElementById('frameA');
myframe.onload=function (funcname) {...};

【问题讨论】:

    标签: javascript jquery events jquery-events


    【解决方案1】:

    检查这个gist 或我的answer 到这个question。那里的代码正是这样做的:

    function iframeURLChange(iframe, callback) {
        var unloadHandler = function () {
            // Timeout needed because the URL changes immediately after
            // the `unload` event is dispatched.
            setTimeout(function () {
                callback(iframe.contentWindow.location.href);
            }, 0);
        };
    
        function attachUnload() {
            // Remove the unloadHandler in case it was already attached.
            // Otherwise, the change will be dispatched twice.
            iframe.contentWindow.removeEventListener("unload", unloadHandler);
            iframe.contentWindow.addEventListener("unload", unloadHandler);
        }
    
        iframe.addEventListener("load", attachUnload);
        attachUnload();
    }
    

    它利用unload 事件。每当一个页面被卸载时,一个新的页面应该开始加载。但是,如果您侦听该事件,您将获得当前 URL,而不是新 URL。通过添加延迟为 0 毫秒的超时,然后然后检查 URL,您将获得新的 iframe URL。

    但是,每次加载新页面时都会删除 unload 侦听器,因此必须在每个 load 上重新添加它。

    不过,该函数会处理所有这些。要使用它,您只需:

    iframeURLChange(document.getElementById("myframe"), function (url) {
        console.log("URL changed:", url);
    });
    

    【讨论】:

      【解决方案2】:

      什么会改变 iframe 的来源?如果您有权访问该代码,那么您可以执行 onload 函数中的任何操作。

      如果链接将其 target 属性设置为 iframe,并且这就是源的变化方式,那么您可以劫持链接点击:

      $('a[target="frameB"]').bind('click', function () {
          //run your onload code here, it will run as the iframe is downloading the new content
      });
      

      另外,顺便说一句,您可以像这样在 jQuery 中为 load 事件绑定一个事件处理程序:

      $('#frameB').bind('load', function () {
          //run onload code here
      });
      

      更新

      站点 -> 框架B -> 框架A

      $("#frameB").contents().find("#frameA").bind('load', function () {
          //load code here
      });
      

      这会选择#frameB 元素(即在当前顶级DOM 中),获取它的内容,找到#frameA 元素,然后为load 事件绑定一个事件处理程序。

      请注意,此代码必须在 #frameB 加载了其 DOM 中已存在的 #frameA 元素后运行。这样的事情可能是个好主意:

      $('#frameB').bind('load', function () {
          $(this).contents().find('#frameA').bind('load', function () {
              //run load code here
          });
      });
      

      更新

      要劫持#frameB 元素中的链接:

      $('#frameB').contents().find('a[target="frameA"]').bind('click', function () {
          /*run your code here*/
      });
      

      这将在#frameB 元素中找到其target 属性设置为frameA 的任何链接,并添加click 事件处理程序。

      同样,这仅在 #frameB iframe 元素已加载(或至少到达 document.ready 事件)时才有效,因此您可以选择它的元素。

      【讨论】:

      • JavaScript 调用将更改 iframeA src(从 iframeA 调用)。我只能访问顶级站点的源代码。站点 --> IFRAME_B --> IFRAME_A。第二个 sn-p 仅在 #frameB 是首页的孩子时才有效,不是吗?我不能 hi.jack 点击,因为不断变化的调用来自 js。 (ifamreA)
      • 您可以选择<iframe>s 中的元素,只要它们在同一个域中(否则相同域策略不允许这样做)。请参阅我有关如何执行此操作的更新。
      • 真的很好,感谢您的帮助,但是加载触发器在iframe加载完成时也会调用,我需要加载前的那一刻。
      • 如何深度使用点击劫持代码? (S->A->B)。也许我可以将它与几个 IF 一起使用。
      • 如果第一个 iframe 中的链接被点击以更改第二个(嵌套)iframe 的来源,那么您可以劫持第一个 iframe 中的链接点击:$('#frameB').contents().find('a[target="frameA"]').bind('click', function () {/*run your code here*/})
      【解决方案3】:

      您也可以尝试采用检测 iframe 何时离开其当前位置的方法。这在某些情况下可能很有用。为此,请将以下代码放入您的 iFarme 源代码中。

      $(window).on('beforeunload', function () {

      alert('加载前...');

      });

      【讨论】:

      • 是的,但如果在 IFrame 的窗口上运行,它可能会在卸载到下一页之前运行。有时document.activeElement.href 会提供有关触发它的任何元素的信息(通常是链接)。我还没有找到一种可靠的方法来捕捉这两个事件。 :(
      • 这是在卸载之前 - 是的,但在卸载之后立即发生的情况 - 加载。我在我的answer 中使用了这个事件,它运行良好。
      【解决方案4】:

      我认为将带有适当事件处理程序的内联 onload 属性添加到 iframe 标记将解决您的问题。

      function onIframeLoad(){
         //Write your code here
      }
      

      标记更改

      <iframe src='..' onload='onIframeLoad()' />
      

      【讨论】:

      • 一旦 iframe 的内容加载完毕,它仍然会触发,对吧?我认为问题是拦截src属性的变化,这样就可以在不等待内容下载的情况下完成一些事情。
      猜你喜欢
      • 2011-03-09
      • 2011-08-23
      • 2010-09-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-05-27
      相关资源
      最近更新 更多