假设我无法控制iframe中的内容,是否有任何方法可以通过父页面检测到其中的src更改?可能是某种负载?
我的最后一招是如果iframe src与以前的相同,则进行1秒间隔测试,但是这样做会导致问题。
如果有帮助,我正在使用jQuery库。
src
DOM中的属性在FireFox或Safari的最新版本中没有更改。@Michiel在下面的回答与我到目前为止所取得的一样好。
假设我无法控制iframe中的内容,是否有任何方法可以通过父页面检测到其中的src更改?可能是某种负载?
我的最后一招是如果iframe src与以前的相同,则进行1秒间隔测试,但是这样做会导致问题。
如果有帮助,我正在使用jQuery库。
src
DOM中的属性在FireFox或Safari的最新版本中没有更改。@Michiel在下面的回答与我到目前为止所取得的一样好。
Answers:
您可能要使用该onLoad
事件,如以下示例所示:
<iframe src="http://www.google.com/" onLoad="alert('Test');"></iframe>
只要iframe中的位置发生变化,警报就会弹出。它适用于所有现代浏览器,但可能不适用于某些较旧的浏览器,例如IE5和早期的Opera。(来源)
如果iframe在父级的同一域中显示页面,则可以使用来访问该位置contentWindow.location
,如以下示例所示:
<iframe src="/test.html" onLoad="alert(this.contentWindow.location);"></iframe>
this.contentWindow.location.href
得到Permission denied to access property 'href'
this.contentWindow.location
适用于其他域。甚至this.contentWindow.location.href
可用于其他域,但仅可用于编写。但是,阅读this.contentWindow.location.href
仅限于同一领域。
基于JQuery <3的答案
$('#iframeid').load(function(){
alert('frame has (re)loaded');
});
如subharb所述,从JQuery 3.0开始,需要将其更改为:
$('#iframe').on('load', function() {
alert('frame has (re)loaded ');
});
https://jquery.com/upgrade-guide/3.0/#breaking-change-load-unload-and-error-removed
if (counter > 1) { // do something on iframe actual change }
(假设计数器在开始时设置为0)
如果您无法控制页面并希望进行某些更改,则可以使用现代方法 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);
<iframe src="http://www.google.com"></iframe>
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/
observe
。这只是一个例子。
注意:仅当iframe的来源相同时,该代码段才有效。
其他答案提出了该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);
});
<iframe id="mainframe" src=""></iframe>
这将成功跟踪src
属性更改以及从iframe本身进行的所有URL更改。
在所有现代浏览器中测试。
iframe始终保留父页面,您应该使用它来检测iframe位于哪个页面中:
HTML代码:
<iframe id="iframe" frameborder="0" scrolling="no" onload="resizeIframe(this)" width="100%" src="www.google.com"></iframe>
Js:
function resizeIframe(obj) {
alert(obj.contentWindow.location.pathname);
}
这是在Commerce SagePay和Commerce Paypoint Drupal模块中使用的方法,该方法主要document.location.href
通过首先加载自己的iframe,然后是外部iframe与旧值进行比较。
因此,基本的想法是将空白页作为占位符加载,并带有其自己的JS代码和隐藏形式。然后父级JS代码将提交该隐藏表单,该表单#action
指向外部iframe。重定向/提交完成后,仍在该页面上运行的JS代码可以跟踪您的document.location.href
值更改。
这是iframe中使用的示例JS:
;(function($) {
Drupal.behaviors.commercePayPointIFrame = {
attach: function (context, settings) {
if (top.location != location) {
$('html').hide();
top.location.href = document.location.href;
}
}
}
})(jQuery);
这是父页面中使用的JS:
;(function($) {
/**
* Automatically submit the hidden form that points to the iframe.
*/
Drupal.behaviors.commercePayPoint = {
attach: function (context, settings) {
$('div.payment-redirect-form form', context).submit();
$('div.payment-redirect-form #edit-submit', context).hide();
$('div.payment-redirect-form .checkout-help', context).hide();
}
}
})(jQuery);
然后,在临时空白登录页面中,您需要包括将重定向到外部页面的表格。
src
在iframe中点击一个链接时,性能变化?我不确定-如果我不得不猜测,是否会说“不”。有一些方法可以监视属性(在Firefox中至少为AFAIK),但是我不确定在这种情况下它是否会有用。