IFrame src изменить событие обнаружения?
Предполагая, что я не контролирую содержимое в iframe, есть ли способ обнаружить изменение src в нем через родительскую страницу? Может быть, какая-то загрузка?
Мое последнее средство - выполнить 1-секундный интервал, если iframe src такой же, как и раньше, но выполнение этого хакерского решения сосало бы.
Я использую библиотеку jQuery, если это помогает.
Ответы
Ответ 1
Возможно, вы захотите использовать событие 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>
Ответ 2
$('#iframeid').load(function(){
alert('frame has (re)loaded');
});
Ответ 3
Если у вас нет контроля над страницей и вы хотите наблюдать за каким-то изменением, то современный метод заключается в использовании 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>
Ответ 4
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);
}
Ответ 5
Вот метод, который используется в 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);
Затем на временной пустой целевой странице вам необходимо включить форму, которая будет перенаправляться на внешнюю страницу.
Ответ 6
Другие ответы предложили событие 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>