обнаружение событий изменения iframe src?
предполагая, что у меня нет контроля над содержимым в iframe, есть ли способ обнаружить изменение src в нем через родительскую страницу? Может быть, какая-то нагрузка?
мое последнее средство-сделать тест с интервалом в 1 секунду, если iframe src такой же, как и раньше, но делать это хакерское решение будет сосать.
Я использую библиотеку jQuery, если это помогает.
7 ответов:
вы можете использовать
onLoad
событие, как в следующем примере:<iframe src="http://www.google.com/" onLoad="alert('Test');"></iframe>
предупреждение будет всплывать всякий раз, когда местоположение в iframe изменяется. Он работает во всех современных браузерах, но может не работать в некоторых очень старых браузерах, таких как IE5 и ранняя Опера. (источник)
если iframe показывает страницу в том же домене родительского, вы сможете получить доступ к локации с
contentWindow.location
, как в следующем пример:<iframe src="/test.html" onLoad="alert(this.contentWindow.location);"></iframe>
ответ на основе JQuery
$('#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
если у вас нет контроля над страницей и вы хотите посмотреть на какие-то изменения, то современный метод должен использовать
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/
On jsFiddle
опубликованный ответ здесь, поскольку исходный вопрос был закрыт как дубликат этого один.
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, а затем внешний.таким образом, в основном идея состоит в том, чтобы загрузить пустую страницу в качестве заполнителя с собственным кодом JS и скрытой формой. Затем Родительский код JS отправит эту скрытую форму, где его
#action
указывает на внешний iframe. Как только произойдет перенаправление / отправка, JS-код, который все еще работает на этой странице, может отслеживать вашdocument.location.href
изменения стоимости.вот пример JS, используемый в iframe:
;(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);
затем во временную пустую целевую страницу нужно включить форму, которая будет перенаправлять на внешнюю страницу.
другие ответы предложили
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
изменения атрибутов, а также любые изменения URL, сделанные из iframe себя.проверен во всех современных браузерах.
Примечание: приведенный выше фрагмент будет работать только в том случае, если iframe имеет тот же источник.
Я суть С этим кодом, а также. Вы можете проверить мой другой ответ тоже. Это идет немного углубленно в то, как это работает.