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.

145
demandé sur Matrym 2010-03-12 01:07:46

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>
164
répondu Daniel Vassallo 2012-12-18 18:54:21

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

50
répondu Michiel 2018-02-21 09:55:25

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.

29
répondu Xotic750 2017-05-23 12:34:39

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);
    }
4
répondu Tarik FAMIL 2016-10-05 09:21:05

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.

1
répondu kenorb 2016-03-16 15:49:08

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.

1
répondu Hristiyan Dodov 2017-12-06 14:25:15

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 ');
});
0
répondu subharb 2017-12-18 09:58:01