iFrame src change event detection?
假设我无法控制iframe中的内容,是否有任何方法可以通过父页面检测到其中的src更改? 可能是某种负载?
我的最后一招是如果iframe src与以前的相同,则进行1秒间隔测试,但是这样做会导致问题。
如果有帮助,我正在使用jQuery库。
您可能要使用
1 | <iframe src="http://www.google.com/" onLoad=";"></iframe> |
只要iframe中的位置发生更改,警报就会弹出。它适用于所有现代浏览器,但可能不适用于某些较旧的浏览器,例如IE5和早期的Opera。 (资源)
如果iframe在父级的同一个域中显示页面,则可以使用
1 | <iframe src="/test.html" onLoad="alert(this.contentWindow.location);"></iframe> |
基于JQuery <3的答案
1 2 3 | $('#iframeid').load(function(){ alert('frame has (re)loaded'); }); |
如subharb所述,从JQuery 3.0开始,需要将其更改为:
1 2 3 | $('#iframe').on('load', function() { alert('frame has (re)loaded '); }); |
https://jquery.com/upgrade-guide/3.0/#breaking-change-load-unload-and-error-removed
如果您无法控制页面并希望注意某种更改,那么现代方法是使用
使用示例,注意
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | 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); |
1 | <iframe src="http://www.google.com"></iframe> |
3秒后输出
1 2 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/ |
在jsFiddle上
由于原始问题已作为此问题的重复部分被关闭,因此在此处发布了答案。
注意:仅当iframe的来源相同时,该代码段才有效。
其他答案提出了
这是一个简单的JavaScript解决方案:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | 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); }); |
1 | <iframe id="mainframe" src=""></iframe> |
这将成功跟踪
在所有现代浏览器中测试。
我也用此代码做了要点。您也可以查看我的其他答案。它将对它的工作原理进行一些深入的介绍。
iframe始终保留父页面,您应该使用它来检测您在iframe中处于哪个页面:
HTML代码:
1 | <iframe id="iframe" frameborder="0" scrolling="no" onload="resizeIframe(this)" width="100%" src="www.google.com"></iframe> |
Js:
1 2 3 | function resizeIframe(obj) { alert(obj.contentWindow.location.pathname); } |
由于Jquery 3.0版,您可能会收到错误消息
TypeError: url.indexOf is not a function
可以很容易地通过修复来解决
1 2 3 | $('#iframe').on('load', function() { alert('frame has (re)loaded '); }); |
这是在Commerce SagePay和Commerce Paypoint Drupal模块中使用的方法,该方法通过首先加载自己的iframe,然后是外部iframe,将
因此,基本上,这个想法是使用自己的JS代码和隐藏形式将空白页作为占位符加载。然后,父JS代码将提交该隐藏表单,该表单的
这是iframe中使用的示例JS:
1 2 3 4 5 6 7 8 9 10 | ;(function($) { Drupal.behaviors.commercePayPointIFrame = { attach: function (context, settings) { if (top.location != location) { $('html').hide(); top.location.href = document.location.href; } } } })(jQuery); |
这是父页面中使用的JS:
1 2 3 4 5 6 7 8 9 10 11 12 | ;(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); |
然后,在临时空白登录页面中,您需要包括将重定向到外部页面的表格。