假设我无法控制 iframe 中的内容,有什么方法可以通过父页面检测到其中的 src 更改?也许某种onload?
如果 iframe src 与以前相同,我最后的手段是进行 1 秒的间隔测试,但是这样做会很糟糕。
如果有帮助,我正在使用 jQuery 库。
假设我无法控制 iframe 中的内容,有什么方法可以通过父页面检测到其中的 src 更改?也许某种onload?
如果 iframe src 与以前相同,我最后的手段是进行 1 秒的间隔测试,但是这样做会很糟糕。
如果有帮助,我正在使用 jQuery 库。
您可能想要使用该onLoad
事件,如下例所示:
<iframe src="http://www.google.com/" onLoad="alert('Test');"></iframe>
只要 iframe 中的位置发生变化,就会弹出警报。它适用于所有现代浏览器,但可能不适用于一些非常旧的浏览器,如 IE5 和早期的 Opera。(来源)
如果 iframe 显示的是与 parent 相同域中的页面,您将能够使用 访问该位置contentWindow.location
,如下例所示:
<iframe src="/test.html" onLoad="alert(this.contentWindow.location);"></iframe>
基于 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/#break-change-load-unload-and-error-removed
如果您无法控制页面并希望观察某种变化,那么现代方法是使用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/
注意:该片段仅在 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);
}
从 Jquery 3.0 版开始,您可能会收到错误消息
TypeError:url.indexOf 不是函数
可以通过以下方式轻松修复
$('#iframe').on('load', function() {
alert('frame has (re)loaded ');
});
这是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);
然后在临时空白登录页面中,您需要包含将重定向到外部页面的表单。