iFrame src改变事件检测?

Mat*_*rym 164 javascript iframe jquery onload

假设我无法控制iframe中的内容,是否有任何方法可以通过父页面检测到src更改?某种上载可能吗?

我的最后一招是如果iframe src与以前相同,则进行1秒间隔测试,但是做这个hacky解决方案会很糟糕.

如果它有帮助我正在使用jQuery库.

Dan*_*llo 182

您可能希望使用该onLoad事件,如以下示例所示:

<iframe src="http://www.google.com/" onLoad="alert('Test');"></iframe>
Run Code Online (Sandbox Code Playgroud)

只要iframe中的位置发生更改,系统就会弹出警报.它适用于所有现代浏览器,但可能无法在IE5和早期Opera等一些非常老的浏览器中使用.(来源)

如果iframe在父级的同一域中显示页面,您将能够访问该位置contentWindow.location,如下例所示:

<iframe src="/test.html" onLoad="alert(this.contentWindow.location);"></iframe>
Run Code Online (Sandbox Code Playgroud)

  • 当我执行`this.contentWindow.location.href`时,我得到'权限被拒绝访问属性'href' (14认同)
  • 你的意思是this.contentWindow.location.href (13认同)
  • this.contentWindow.location.href不会工作bcoz你正在做一个跨源请求.:(所有浏览器现在都限制它. (3认同)
  • 更正:`this.contentWindow.location`可用于其他域.甚至`this.contentWindow.location.href`也可用于其他域,但仅限于写入.但是,读取`this.contentWindow.location.href`仅限于同一个域. (2认同)
  • 这是 **未定义** 不再有效的解决方案。 (2认同)

Mic*_*iel 56

答案基于JQuery <3

$('#iframeid').load(function(){
    alert('frame has (re)loaded');
});
Run Code Online (Sandbox Code Playgroud)

正如subharb所提到的,从JQuery 3.0开始,需要将其更改为:

$('#iframe').on('load', function() {
    alert('frame has (re)loaded ');
});
Run Code Online (Sandbox Code Playgroud)

https://jquery.com/upgrade-guide/3.0/#breaking-change-load-unload-and-error-removed

  • 不完全按计划工作。它在初始页面加载时触发警报。根据您对此代码的计划(对我而言,我正在为表单提交页面上的对话框设置动画),此解决方案将不起作用。 (3认同)

Xot*_*750 35

如果您无法控制页面并希望观察某种变化,那么现代方法就是使用 MutationObserver

它的一个使用示例,观察src属性改变iframe

new MutationObserver(function(mutations) {
  mutations.some(function(mutation) {
    if (mutation.type === 'attributes' && mutation.attributeName === 'src') {
      console.log(mutation);
      console.log('Old src: ', mutation.oldValue);
      console.log('New src: ', mutation.target.src);
      return true;
    }

    return false;
  });
}).observe(document.body, {
  attributes: true,
  attributeFilter: ['src'],
  attributeOldValue: true,
  characterData: false,
  characterDataOldValue: false,
  childList: false,
  subtree: true
});

setTimeout(function() {
  document.getElementsByTagName('iframe')[0].src = 'http://jsfiddle.net/';
}, 3000);
Run Code Online (Sandbox Code Playgroud)
<iframe src="http://www.google.com"></iframe>
Run Code Online (Sandbox Code Playgroud)

3秒后输出

MutationRecord {oldValue: "http://www.google.com", attributeNamespace: null, attributeName: "src", nextSibling: null, previousSibling: null…}
Old src:  http://www.google.com
New src:  http://jsfiddle.net/ 
Run Code Online (Sandbox Code Playgroud)

jsFiddle上

在这里发布答案,因为原始问题被关闭作为这个问题的副本.

  • 但在我的情况下,frame.contentDocument.URL更改(从框架内的链接)而不是src.我可以看吗? (4认同)

小智 6

iframe始终保留父页面,您应该使用它来检测您在iframe中的哪个页面:

Html代码:

<iframe id="iframe" frameborder="0" scrolling="no" onload="resizeIframe(this)" width="100%" src="www.google.com"></iframe>
Run Code Online (Sandbox Code Playgroud)

JS:

    function resizeIframe(obj) {
        alert(obj.contentWindow.location.pathname);
    }
Run Code Online (Sandbox Code Playgroud)


Hri*_*dov 5

其他答案提出了该load事件,但在加载iframe中的新页面后将触发该事件。可能需要在URL更改立即通知您,而不是在加载新页面后通知您。

这是一个简单的JavaScript解决方案:

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

iframeURLChange(document.getElementById("mainframe"), function (newURL) {
    console.log("URL changed:", newURL);
});
Run Code Online (Sandbox Code Playgroud)
<iframe id="mainframe" src=""></iframe>
Run Code Online (Sandbox Code Playgroud)

这将成功跟踪src属性更改以及从iframe本身进行的所有URL更改。

在所有现代浏览器中测试。

注意:以上代码段仅在iframe起源相同的情况下有效。

我做了一个要点与此代码。您也可以查看我的其他答案。它将对它的工作原理进行一些深入的介绍。

  • 在 Chrome 95 中使用 stackoverflow 中的“运行代码片段”按钮运行此代码片段会显示以下错误: { "message": "Uncaught SecurityError: Blocked aframe with origin \"null\" from accessing a cross-originframe. ”,“文件名”:“https://stacksnippets.net/js”,“lineno”:24,“colno”:30} (2认同)

sub*_*arb 5

从 Jquery 3.0 版本开始你可能会得到一个错误

类型错误:url.indexOf 不是函数

通过这样做可以轻松修复

$('#iframe').on('load', function() {
    alert('frame has (re)loaded ');
});
Run Code Online (Sandbox Code Playgroud)