237 votes

Détection des événements de changement de src d'iFrame ?

En supposant que je n'ai aucun contrôle sur le contenu de l'iframe, y a-t-il un moyen de détecter un changement de src via la page parent ? Une sorte de onload peut-être ?

Mon dernier recours est de faire un test à intervalle d'une seconde pour voir si la src de l'iframe est la même qu'avant, mais faire cette solution de fortune serait nul.

J'utilise la bibliothèque jQuery si cela peut aider.

5 votes

Est-ce que le src change-t-elle lorsqu'on clique sur un lien dans l'iframe ? Je ne suis pas sûr de cela - si je devais deviner, je dirais "non". Il y a sont Il existe des moyens de contrôler les propriétés (dans Firefox au moins AFAIK) mais je ne suis pas sûr que cela soit utile dans ce cas.

0 votes

J'essaie de mettre en œuvre quelque chose de ce genre, et je peux confirmer que la fonction src dans le DOM fait no changement dans les dernières versions de FireFox ou de Safari. La réponse de @Michiel ci-dessous est la meilleure que j'ai pu obtenir jusqu'à présent.

244voto

Daniel Vassallo Points 142049

Vous pouvez utiliser le onLoad comme dans l'exemple suivant :

<iframe src="http://www.google.com/" onLoad="alert('Test');"></iframe>

L'alerte s'affichera chaque fois que l'emplacement dans l'iframe changera. Elle fonctionne dans tous les navigateurs modernes, mais peut ne pas fonctionner dans certains navigateurs très anciens comme IE5 et les premiers Opera. ( Source : )

Si l'iframe affiche une page dans le même domaine que le parent vous pourriez accéder à l'emplacement avec contentWindow.location comme dans l'exemple suivant :

<iframe src="/test.html" onLoad="alert(this.contentWindow.location);"></iframe>

14 votes

Vous voulez dire this.contentWindow.location.href

0 votes

@Daniel Vassallo en supposant que vous adoptiez cette approche lorsque vous souhaitez gérer un problème de sécurité, quelqu'un ne peut-il pas simplement remplacer l'événement onLoad et modifier le contenu de l'iframe ?

17 votes

Quand je le fais this.contentWindow.location.href Je reçois Permission denied to access property 'href'

62voto

Michiel Points 987

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

3 votes

Ça ne fonctionne pas exactement comme prévu. Il déclenche l'alerte lors du chargement initial de la page. En fonction de ce que vous prévoyez pour ce code (pour moi, j'anime la boîte de dialogue hors de la page à l'envoi du formulaire), cette solution ne fonctionnera pas.

0 votes

@stracigh, c'est correct, l'événement se déclenchera chaque fois que le cadre se chargera, donc aussi la première fois lors du chargement initial de la page. Si vous ne voulez pas que votre code soit déclenché la première fois, vous devez d'une manière ou d'une autre détecter qu'il s'agit du premier chargement du cadre et revenir.

0 votes

@FooBar, Oui, il fonctionne sur plusieurs domaines, c'est d'ailleurs pour cela que je l'ai utilisé. Mais vous ne pouvez pas accéder à la page dans l'iFrame avec javascript quand cette page est sur un autre domaine.

52voto

Xotic750 Points 6649

Si vous n'avez pas le contrôle de la page et que vous souhaitez surveiller un changement quelconque, la méthode moderne consiste à utiliser MutationObserver

Un exemple de son utilisation, en surveillant le src à la modification 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/ 

Sur jsFiddle

Réponse postée ici car la question originale a été fermée en tant que doublon de celle-ci.

0 votes

Que faire si j'utilise des composants Web et que l'un de mes composants personnalisés possède un attribut src ? Je pense que ce système le détecterait accidentellement.

0 votes

Ensuite, vous changez les options sur observe . Ce n'est qu'un exemple.

0 votes

@PaulRoub a supprimé le lien jsfiddle (ce devait être une erreur de copier/coller) et a inclus le code sous forme d'extrait.

26voto

Hristiyan Dodov Points 1627

Note : L'extrait ne fonctionnerait que si l'iframe a la même origine.

D'autres réponses ont proposé le load mais il déclenche après la nouvelle page dans l'iframe est chargée. Vous pourriez avoir besoin d'être informé immédiatement après le changement d'URL et non après le chargement de la nouvelle page.

Voici une solution simple en 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>

Cela permettra de suivre avec succès le src ainsi que tout changement d'URL effectué à l'intérieur de l'iframe lui-même.

Testé dans tous les navigateurs modernes.

J'ai fait un Gist avec ce code également. Vous pouvez consulter mes autres réponse aussi. Il explique en détail comment cela fonctionne.

7voto

Tarik FAMIL Points 409

L'iframe conserve toujours la page parente, vous devriez l'utiliser pour détecter dans quelle page vous vous trouvez 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);
    }

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X