iFrame src ¿detección de eventos de cambio?
Asumiendo que no tengo control sobre el contenido en el iframe, ¿hay alguna manera de que pueda detectar un cambio de src en él a través de la página principal? ¿Algún tipo de carga tal vez?
Mi último recurso es hacer una prueba de intervalo de 1 segundo si el iframe src es el mismo que antes, pero hacer esta solución hacky sería una mierda.
Estoy usando la biblioteca jQuery si ayuda.
7 answers
Es posible que desee utilizar el evento onLoad
, como en el siguiente ejemplo:
<iframe src="http://www.google.com/" onLoad="alert('Test');"></iframe>
La alerta aparecerá cada vez que cambie la ubicación dentro del iframe. Funciona en todos los navegadores modernos, pero puede que no funcione en algunos navegadores muy antiguos como IE5 y early Opera. (Fuente )
Si el iframe muestra una página dentro del mismo dominio del padre, podrá acceder a la ubicación con contentWindow.location
, como en el siguiente ejemplo:
<iframe src="/test.html" onLoad="alert(this.contentWindow.location);"></iframe>
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-12-18 18:54:21
Respuesta basada en jQuery
$('#iframeid').load(function(){
alert('frame has (re)loaded');
});
Como se menciona en subharb, a partir de jQuery 3.0 esto debe cambiarse a:
$('#iframe').on('load', function() {
alert('frame has (re)loaded ');
});
Https://jquery.com/upgrade-guide/3.0/#breaking-change-load-unload-and-error-removed
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-02-21 09:55:25
Si no tiene control sobre la página y desea observar algún tipo de cambio, entonces el método moderno es usar MutationObserver
Un ejemplo de su uso, observando el atributo src
al cambio de un 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>
Salida después de 3 segundos
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
La respuesta publicada aquí como pregunta original se cerró como un duplicado de esta.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:34:39
El iframe siempre mantiene la página principal, debe usar esto para detectar en qué página se encuentra en el iframe:
Código 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);
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-10-05 09:21:05
Aquí está el método que se usa en Commerce SagePay y en Commerce Paypoint Los módulos Drupal que básicamente comparan document.location.href
con el valor antiguo cargando primero su propio iframe, luego uno externo.
Así que básicamente la idea es cargar la página en blanco como un marcador de posición con su propio código JS y forma oculta. Luego el código JS padre enviará esa forma oculta donde su #action
apunta al iframe externo. Una vez que ocurre el redireccionamiento / envío, el código JS que aún se está ejecutando en esa página puede rastrear sus cambios de valor document.location.href
.
Aquí está el ejemplo JS usado en iframe:
;(function($) {
Drupal.behaviors.commercePayPointIFrame = {
attach: function (context, settings) {
if (top.location != location) {
$('html').hide();
top.location.href = document.location.href;
}
}
}
})(jQuery);
Y aquí está JS usado en la página principal:
;(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);
Luego, en la página de destino temporal en blanco, debe incluir el formulario que redirigirá a la página externa.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-03-16 15:49:08
Otras respuestas propusieron el evento load
, pero se dispara después de que se cargue la nueva página en el iframe. Es posible que deba ser notificado inmediatamente después de que la URL cambie, no después de que se cargue la nueva página.
Aquí hay una solución simple de 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>
Esto rastreará con éxito los cambios en el atributo src
, así como cualquier cambio de URL realizado dentro del iframe.
Probado en todos los modernos navegador.
Nota: El fragmento de código anterior solo funcionaría si el iframe tiene el mismo origen.
Hice un gist con este código también. Usted puede comprobar mi otra respuesta también. Profundiza un poco en cómo funciona esto.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-12-06 14:25:15
Desde la versión 3.0 de Jquery es posible que obtenga un error
TypeError: url.indexOf no es una función
Que se puede arreglar fácilmente haciendo
$('#iframe').on('load', function() {
alert('frame has (re)loaded ');
});
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-12-18 09:58:01