web-dev-qa-db-fra.com

Rappel Javascript lorsque le chargement d’IFRAME est terminé?

J'ai besoin d'exécuter un rappel lorsqu'un IFRAME a fini de se charger. Je n'ai aucun contrôle sur le contenu de l'IFRAME, je ne peux donc pas déclencher le rappel à partir de là.

Cet IFRAME est créé par programme et je dois transmettre ses données en tant que variable dans le rappel, ainsi que détruire l'iframe.

Des idées?

EDIT:

Voici ce que j'ai maintenant:

function xssRequest(url, callback)
{
    var iFrameObj = document.createElement('IFRAME');
    iFrameObj.src = url;            
    document.body.appendChild(iFrameObj);   

    $(iFrameObj).load(function() 
    {
        document.body.removeChild(iFrameObj);
        callback(iFrameObj.innerHTML);
    });
}

Ce rappel avant le chargement de l'iFrame, de sorte qu'il ne renvoie aucune donnée.

143
FlySwat

Tout d’abord, utilisez le nom de la fonction xssRequest vous essayez d’essayer une requête multisite - ce qui, s’il est exact, ne vous permettra pas de lire le contenu de l’iframe.

D'un autre côté, si l'URL de l'iframe se trouve sur votre domaine, vous pouvez accéder au corps de celui-ci, mais j'ai constaté que, si j'utilise un délai d'attente pour supprimer l'iframe, le rappel fonctionne correctement:

// possibly excessive use of jQuery - but I've got a live working example in production
$('#myUniqueID').load(function () {
  if (typeof callback == 'function') {
    callback($('body', this.contentWindow.document).html());
  }
  setTimeout(function () {$('#frameId').remove();}, 50);
});
49
Remy Sharp

J'utilise jQuery et, étonnamment, cela semble charger car je viens de tester et de charger une page lourde et je n'ai pas reçu l'alerte pendant quelques secondes jusqu'à ce que je voie le chargement de l'iframe:

$('#the_iframe').load(function(){
    alert('loaded!');
});

Donc, si vous ne voulez pas utiliser jQuery, jetez un coup d'œil à leur code source et voyez si cette fonction se comporte différemment avec les éléments iframe DOM, je la regarderai moi-même plus tard car je suis intéressée et posterai ici. Aussi, j'ai seulement testé dans le dernier chrome.

35
Neo

Le code innerHTML de votre iframe est vide, car votre balise iframe n'entoure aucun contenu du document parent. Pour obtenir le contenu de la page référencée par l'attribut src de l'iframe, vous devez accéder à la propriété contentDocument de l'iframe. Une exception sera levée si le src provient d’un domaine différent. Il s'agit d'une fonctionnalité de sécurité qui vous empêche d'exécuter du code JavaScript arbitraire sur la page d'un autre utilisateur, ce qui créerait une vulnérabilité de script intersite. Voici un exemple de code illustrant ce dont je parle:

<script src="http://prototypejs.org/assets/2009/8/31/prototype.js" type="text/javascript"></script>

<h1>Parent</h1>

<script type="text/javascript">
function on_load(iframe) {
  try {
    // Displays the first 50 chars in the innerHTML of the
    // body of the page that the iframe is showing.
    // EDIT 2012-04-17: for wider support, fallback to contentWindow.document
    var doc = iframe.contentDocument || iframe.contentWindow.document;
    alert(doc.body.innerHTML.substring(0, 50));
  } catch (e) {
    // This can happen if the src of the iframe is
    // on another domain
    alert('exception: ' + e);
  }
}
</script>
<iframe id="child" src="iframe_content.html" onload="on_load(this)"></iframe>

Pour approfondir l’exemple, essayez d’utiliser ceci comme contenu de l’iframe:

<h1>Child</h1>

<a href="http://www.google.com/">Google</a>

<p>Use the preceeding link to change the src of the iframe
to see what happens when the src domain is different from
that of the parent page</p>
8
allyourcode

J'ai dû faire cela dans des cas où des documents tels que Word Docs et PDF étaient transmis à l'iframe et trouvaient une solution qui fonctionnait plutôt bien. La clé gère l'événement onreadystatechanged sur l'iframe.

Disons que le nom de votre cadre est "myIframe". D'abord quelque part dans votre code de démarrage (je le fais en ligne n'importe où après l'iframe) ajoutez quelque chose comme ceci pour enregistrer le gestionnaire d'événements:

document.getElementById('myIframe').onreadystatechange = MyIframeReadyStateChanged;

Je n'étais pas capable d'utiliser un attribut onreadystatechage sur l'iframe, je ne me souviens pas pourquoi, mais l'application devait fonctionner dans IE 7 et Safari 3, ce qui a peut-être été un facteur déterminant.

Voici un exemple de comment obtenir l'état complet:

function MyIframeReadyStateChanged()
{
    if(document.getElementById('myIframe').readyState == 'complete')
    {
        // Do your complete stuff here.
    }
}
7
Ryan Cook

Je voulais cacher l'attente lorsque le contenu du cadre i est entièrement chargé sur IE, j'ai littéralement essayé toutes les solutions mentionnées dans Stackoverflow.Com, mais rien ne fonctionnait comme je le voulais.

Ensuite, j’ai eu l’idée que lorsque le contenu de la trame i serait entièrement chargé, l’événement de chargement $ (Window) pourrait être déclenché. Et c'est exactement ce qui s'est passé. J'ai donc écrit ce petit script et travaillé comme par magie:

     $(window).load(function () {
     //alert("Done window ready ");
     var lblWait = document.getElementById("lblWait");
     if (lblWait != null ) {
         lblWait.style.visibility = "false";
         document.getElementById("divWait").style.display = "none";
     }
 });

J'espère que cela t'aides.

6
Nada N. Hantouli

J'ai eu un problème similaire à toi. Ce que j'ai fait est que j'utilise quelque chose appelé jQuery. Voici ce que vous faites dans le code javascript:

$(function(){ //this is regular jQuery code. It waits for the dom to load fully the first time you open the page.

    $("#myIframeId").load(function(){
       callback($("#myIframeId").html());
       $("#myIframeId").remove();

    });

});

Il semble que vous supprimiez iFrame avant de récupérer le code HTML. Maintenant, je vois un problème avec ça: p

J'espère que cela t'aides :).

2
Automatico

J'ai un code similaire dans mes projets qui fonctionne bien. En adaptant mon code à votre fonction, une solution pourrait être la suivante:

function xssRequest(url, callback)
{
    var iFrameObj = document.createElement('IFRAME');
    iFrameObj.id = 'myUniqueID';
    document.body.appendChild(iFrameObj);       
    iFrameObj.src = url;                        

    $(iFrameObj).load(function() 
    {
        callback(window['myUniqueID'].document.body.innerHTML);
        document.body.removeChild(iFrameObj);
    });
}

Peut-être avez-vous un innerHTML vide parce que (une ou les deux causes): 1. vous devriez l'utiliser avec l'élément body 2. vous avez supprimé l'iframe du DOM de votre page

2
Pier Luigi

Je pense que le chargement est juste. Ce qui n’est pas correct, c’est la façon dont vous utilisez pour récupérer le contenu de iframe content dom.

Ce dont vous avez besoin, c'est le code HTML de la page chargée dans l'iframe et non le code HTML de l'objet iframe.

Ce que vous devez faire est d'accéder au document de contenu avec iFrameObj.contentDocument. Cela renvoie le dom de la page chargée dans l'iframe, s'il se trouve sur le même domaine que la page en cours.

Je voudrais récupérer le contenu avant de supprimer l'iframe.

J'ai testé sous firefox et opera.

Ensuite, je pense que vous pouvez récupérer vos données avec $(childDom).html() ou $(childDom).find('some selector') ...

1
user142830

J'ai eu exactement le même problème dans le passé et la seule façon de le résoudre était d'ajouter le rappel à la page iframe. Bien sûr, cela ne fonctionne que lorsque vous avez le contrôle sur le contenu de l'iframe.

0
roryf