it-swarm.com.de

Javascript Callback wenn IFRAME fertig geladen ist?

Ich muss einen Rückruf ausführen, wenn ein IFRAME vollständig geladen wurde. Ich habe keine Kontrolle über den Inhalt im IFRAME, daher kann ich den Rückruf von dort nicht auslösen.

Dieser IFRAME wird programmgesteuert erstellt, und ich muss seine Daten als Variable im Rückruf übergeben sowie den iframe zerstören.

Irgendwelche Ideen?

EDIT:

Folgendes habe ich jetzt:

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);
    });
}

Dieser Rückruf, bevor der iFrame geladen wurde, sodass für den Rückruf keine Daten zurückgegeben wurden.

143
FlySwat

Zunächst wird der Funktionsname angegeben xssRequest. Es scheint, als würden Sie eine standortübergreifende Anforderung ausführen. Wenn dies zutrifft, können Sie den Inhalt des iframe nicht lesen.

Wenn sich die URL des Iframes in Ihrer Domain befindet, können Sie auf den Text zugreifen. Ich habe jedoch festgestellt, dass der Rückruf ordnungsgemäß funktioniert, wenn ich den Iframe mithilfe einer Zeitüberschreitung entferne:

// 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

Ich verwende jQuery und überraschenderweise wird dies geladen, da ich gerade eine umfangreiche Seite getestet und geladen habe und einige Sekunden lang keine Warnung erhalten habe, bis ich das Laden des Iframes sah:

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

Wenn Sie jQuery nicht verwenden möchten, sehen Sie sich den Quellcode an und prüfen Sie, ob sich diese Funktion bei iframe-DOM-Elementen anders verhält. Ich werde es mir später ansehen, wenn ich interessiert bin und hier posten. Auch habe ich nur das neuste Chrom getestet.

35
Neo

Das innerHTML Ihres iframe ist leer, da Ihr iframe-Tag keinen Inhalt im übergeordneten Dokument umgibt. Um den Inhalt von der Seite abzurufen, auf die durch das Attribut src des iframe verwiesen wird, müssen Sie auf die Eigenschaft contentDocument des iframe zugreifen. Eine Ausnahme wird jedoch ausgelöst, wenn der src aus einer anderen Domäne stammt. Dies ist eine Sicherheitsfunktion, die Sie daran hindert, willkürliches JavaScript auf der Seite einer anderen Person auszuführen, wodurch eine Sicherheitsanfälligkeit bezüglich siteübergreifender Skripterstellung entsteht. Hier ist ein Beispielcode, der veranschaulicht, wovon ich spreche:

<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>

Versuchen Sie, dies als Inhalt des Iframes zu verwenden, um das Beispiel zu fördern:

<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

Ich musste dies in Fällen tun, in denen Dokumente wie Word-Dokumente und PDFs zum iframe gestreamt wurden und eine Lösung gefunden haben, die ziemlich gut funktioniert. Der Schlüssel behandelt das Ereignis onreadystatechanged auf dem iframe.

Nehmen wir an, der Name Ihres Frames lautet "myIframe". Zuerst irgendwo in Ihrem Codestart (ich mache es irgendwo inline nach dem iframe) fügen Sie so etwas hinzu, um den Ereignishandler zu registrieren:

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

Ich konnte kein onreadystatechage-Attribut für den iframe verwenden, ich kann mich nicht erinnern, warum, aber die App musste in IE 7 und Safari 3 funktionieren, sodass dies möglicherweise ein Faktor war.

Hier ist ein Beispiel, wie Sie den vollständigen Status abrufen können:

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

Ich wollte das wartende Spinner-Div verstecken, wenn der i-Frame-Inhalt vollständig im IE geladen ist. Ich habe buchstäblich jede in Stackoverflow.Com erwähnte Lösung ausprobiert, aber nichts funktionierte so, wie ich wollte.

Dann hatte ich eine Idee, dass, wenn der i-Frame-Inhalt vollständig geladen ist, das Ladeereignis $ (Window) ausgelöst werden könnte. Und genau das ist passiert. Also schrieb ich dieses kleine Skript und arbeitete wie 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";
     }
 });

Hoffe das hilft.

6

Ich hatte ein ähnliches Problem wie Sie. Was ich getan habe, ist, dass ich etwas benutze, das jQuery heißt. Was Sie dann im Javascript-Code tun, ist Folgendes:

$(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();

    });

});

Es scheint, als würden Sie Ihren iFrame löschen, bevor Sie den HTML-Code daraus abrufen. Nun sehe ich ein Problem damit: p

Hoffe das hilft :).

2
Automatico

Ich habe einen ähnlichen Code in meinen Projekten, der gut funktioniert. Wenn Sie meinen Code an Ihre Funktion anpassen, könnte dies die folgende Lösung sein:

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);
    });
}

Möglicherweise haben Sie ein leeres innerHTML, weil (eine oder beide Ursachen): 1. Sie sollten es gegen das body-Element verwenden. 2. Sie haben den iframe aus dem DOM Ihrer Seite entfernt

2
Pier Luigi

Ich denke, das Ladeereignis ist richtig. Was nicht richtig ist, ist die Art und Weise, wie Sie den Inhalt von iframe content dom abrufen.

Was Sie brauchen, ist der HTML-Code der im Iframe geladenen Seite, nicht der HTML-Code des Iframe-Objekts.

Sie müssen lediglich mit iFrameObj.contentDocument Auf das Inhaltsdokument zugreifen. Dies gibt die Domains der Seite zurück, die im Iframe geladen wurden, wenn sie sich in derselben Domain wie die aktuelle Seite befinden.

Ich würde den Inhalt zurückerhalten, bevor ich den Iframe entferne.

Ich habe in Firefox und Oper getestet.

Dann denke ich, dass Sie Ihre Daten mit $(childDom).html() oder $(childDom).find('some selector') ... abrufen können.

1
user142830

Ich hatte in der Vergangenheit genau das gleiche Problem und konnte es nur beheben, indem ich den Rückruf zur iframe-Seite hinzufügte. Das funktioniert natürlich nur, wenn Sie die Kontrolle über den Iframe-Inhalt haben.

0
roryf