Rappel Javascript quand le chargement D'IFRAME est terminé?

j'ai besoin d'exécuter un callback quand une IFRAME a terminé le chargement. Je n'ai aucun contrôle sur le contenu de L'IFRAME, donc je ne peux pas lancer le rappel à partir de là.

cette IFRAME est créée de manière programmatique, et j'ai besoin de passer ses données en tant que variable dans le callback, ainsi que de 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 callsback avant le chargement de l'iFrame, de sorte que le callback n'a pas de données retournées.

137
demandé sur FlySwat 2008-10-02 23:21:44

10 réponses

tout D'abord, en allant par le nom de fonction xssRequest il semble que vous essayez cross Site request - qui si c'est exact, vous n'allez pas être en mesure de lire le contenu de l'iframe.

d'un autre côté, si l'URL de l'iframe est sur votre domaine, vous pouvez accéder au corps, mais j'ai trouvé que si j'utilise un timeout pour supprimer l'iframe le callback fonctionne très bien:

// 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);
});
47
répondu Remy Sharp 2008-10-16 18:31:38

j'utilise jQuery et étonnamment cela semble charger alors que je viens de tester et chargé une page lourde et je n'ai pas eu l'alerte pendant quelques secondes jusqu'à ce que j'ai vu la charge iframe:

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

donc si vous ne voulez pas utiliser jQuery jetez un oeil à leur code source et voir si cette fonction se comporte différemment avec iframe éléments DOM, je vais regarder moi-même plus tard que je suis intéressé et poster ici. De plus, je n'ai testé que dans le dernier chrome.

34
répondu Neo 2013-05-03 16:12:24

l'innerHTML de votre iframe est vide parce que votre étiquette iframe n'entoure aucun contenu dans le document parent. Pour obtenir le contenu de la page mentionnée par l'attribut src de l'iframe, vous devez accéder à la propriété contentDocument de l'iframe. Une exception sera lancé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 JavaScript arbitraire sur la page de quelqu'un d'autre, ce qui créerait un script cross-site vulnérabilité. Voici un exemple de code qui illustre 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 compléter 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
répondu allyourcode 2012-04-18 06:39:28

j'ai dû le faire dans les cas où des documents tels que word docs et pdfs ont été redirigés vers l'iframe et ont trouvé une solution qui fonctionne assez bien. La clé est de gérer l'événement onreadystatechanged sur l'iframe.

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

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

Je n'ai pas pu utilisez un attribut onreadystatechage sur l'iframe, Je ne me souviens pas pourquoi, mais l'application devait fonctionner dans IE 7 et Safari 3, de sorte que peut DE été un facteur.

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

function MyIframeReadyStateChanged()
{
    if(document.getElementById('myIframe').readyState == 'complete')
    {
        // Do your complete stuff here.
    }
}
6
répondu Ryan Cook 2008-12-05 05:33:44

j'ai voulu cacher le spinner div en attente quand le contenu du cadre i est complètement chargé sur IE, j'ai essayé littéralement chaque solution mentionnée dans Stackoverflow.Com mais rien n'a fonctionné comme je le voulais.

alors j'ai eu une idée, que lorsque le contenu du cadre i est complètement chargé, l'événement $(Window ) load pourrait être déclenché. Et c'est exactement ce qui s'est passé. Donc, j'ai écrit ce petit script, et j'ai 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";
     }
 });

Espérons que cette aide.

6
répondu Nada N. Hantouli 2014-12-10 08:16:19

j'ai un code similaire dans mes projets qui fonctionne très 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 que vous avez un innerHTML vide parce que (une ou les deux causes): 1. vous devriez l'utiliser contre l'élément du corps 2. vous avez supprimé l'iframe de votre page DOM

2
répondu Pier Luigi 2008-10-15 13:52:53

j'ai eu le même problème que vous. Ce que j'ai fait, c'est que j'utilise quelque chose appelé jQuery. Ce que vous faites ensuite dans le code javascript est ceci:

$(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 supprimez vous iFrame avant de saisir le html de lui. Maintenant, je vois un problème avec cela: p

Espérons que cela aide :).

2
répondu Automatico 2012-07-24 17:39:08

je pense que l'événement load est correct. Ce qui n'est pas juste, c'est la façon dont vous utilisez pour retirer le contenu d'iframe content dom.

ce qu'il vous faut, c'est le html de la page chargée dans l'iframe et non le html de l'objet iframe.

ce que vous devez faire est d'accéder au document de contenu avec iFrameObj.contentDocument . Renvoie le dom de la page chargée à l'intérieur de l'iframe, si c'est sur le même domaine de la page actuelle.

je voudrais retirez le contenu avant d'enlever l'iframe.

j'ai testé dans firefox et opera.

alors je pense que vous pouvez retreive vos données avec $(childDom).html() ou $(childDom).find('some selector') ...

1
répondu 2009-08-25 13:33:03

j'ai eu exactement le même problème dans le passé et le seul moyen que j'ai trouvé pour le corriger était d'ajouter le rappel dans la page iframe. Bien sûr, cela ne fonctionne que lorsque vous avez le contrôle sur le contenu iframe.

0
répondu roryf 2008-10-02 19:34:53

en utilisant onload attrbute résoudra votre problème.

voici un exemple.

function a() {
alert("Your iframe has been loaded");
}
<iframe src="https://stackoverflow.com" onload="a()"></iframe>

C'est ça que tu veux?

Cliquez ici pour plus d'informations.

0
répondu 2018-03-26 08:07:51