iFrame src détection des événements de changement?
, en Supposant que je n'ai aucun contrôle sur le contenu de l'iframe, est-il possible que je peux détecter un src changement via la page parent? Une sorte de onload peut-être?
mon dernier recours est de faire un test d'intervalle de 1 seconde si l'iframe src est le même qu'il était avant, mais faire cette solution hacky serait nul.
j'utilise la bibliothèque jQuery si ça peut aider.
7 réponses
vous pouvez utiliser l'événement onLoad
, comme dans l'exemple suivant:
<iframe src="http://www.google.com/" onLoad="alert('Test');"></iframe>
l'alerte apparaîtra chaque fois que l'emplacement dans l'iframe change. Il fonctionne dans tous les navigateurs modernes, mais ne fonctionne peut-être pas dans certains navigateurs très anciens comme IE5 et Early Opera. ( Source )
si l'iframe affiche une page dans le même domaine du parent , vous pourrez accéder au emplacement avec contentWindow.location
, comme dans l'exemple suivant:
<iframe src="/test.html" onLoad="alert(this.contentWindow.location);"></iframe>
réponse basée sur JQuery < 3
$('#iframeid').load(function(){
alert('frame has (re)loaded');
});
comme mentionné par subharb, à partir de JQuery 3.0, cela doit être changé en:
$('#iframe').on('load', function() {
alert('frame has (re)loaded ');
});
https://jquery.com/upgrade-guide/3.0/#breaking-change-load-unload-and-error-removed
si vous n'avez aucun contrôle sur la page et que vous souhaitez surveiller une sorte de changement, alors la méthode moderne est d'utiliser MutationObserver
un exemple de son utilisation, à l'affût de l'attribut src
pour le changement d'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>
sortie après 3 secondes
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
réponse affichée ici comme question originale a été fermé comme une copie de celui-ci.
l'iframe conserve toujours la page mère, vous devez l'utiliser pour détecter dans quelle page vous êtes dans l'iframe:
code 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);
}
Voici la méthode utilisée dans commerce SagePay et dans Commerce Paypoint Drupal modules qui compare fondamentalement document.location.href
avec l'ancienne valeur en chargeant d'abord son propre iframe, puis externe.
donc fondamentalement l'idée est de charger la page blanche comme un conteneur avec son propre code JS et forme cachée. Puis le code JS parent soumettra cette forme cachée où son #action
pointe vers l'extérieur iframe. Une fois que la redirection/submit se produit, le code JS qui tourne encore sur cette page peut suivre vos changements de valeur document.location.href
.
voici l'exemple de JS utilisé dans iframe:
;(function($) {
Drupal.behaviors.commercePayPointIFrame = {
attach: function (context, settings) {
if (top.location != location) {
$('html').hide();
top.location.href = document.location.href;
}
}
}
})(jQuery);
et voici JS utilisé dans la page parent:
;(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);
ensuite, dans la page d'accueil vide temporaire, vous devez inclure le formulaire qui sera redirigé vers la page externe.
D'autres réponses proposaient l'événement load
, mais il déclenche après la nouvelle page dans l'iframe est chargée. Vous pourriez avoir besoin d'être avisé immédiatement après les changements D'URL , pas après que la nouvelle page est chargée.
Voici une solution JavaScript simple:
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>
cela permettra de suivre avec succès les changements d'attribut src
, ainsi que tout changement D'URL effectué à partir de l'iframe lui-même.
Testé dans tous les navigateurs modernes.
Note: L'extrait ci-dessus ne fonctionnerait que si l'iframe est de même origine.
j'ai fait un gist avec ce code aussi. Vous pouvez vérifier mon autre réponse aussi. Elle va un peu en profondeur sur la façon dont cela fonctionne.
depuis la version 3.0 de Jquery vous pourriez obtenir une erreur
TypeError: url.indexOf n'est pas une fonction
qui peut être facilement fixé en faisant
$('#iframe').on('load', function() {
alert('frame has (re)loaded ');
});