it-swarm.com.de

iframe-Verhalten von onload vs. addEventListener ('load')

Ich habe mit dem Hinzufügen von verborgenen Iframe-Elementen zu einer Seite herumgespielt, und ich möchte das DOM der einmal geladenen Elemente manipulieren. Ich habe festgestellt, dass ich das DOM nicht unmittelbar nach dem Hinzufügen des Iframes zu einer Seite bearbeiten kann, da es noch nicht geladen wurde. Dies kann nicht mit dem Ereignis DOMContentLoaded durchgeführt werden, da dieses gegen das Dokument ausgelöst wird, das nicht im iframe vorhanden ist, bis es der Seite hinzugefügt wird. Daher müssen Sie das Ereignis load verwenden.

Hier ist ein Testcode:

var iframe = document.createElement('iframe');
iframe.onload = function() { console.log('loaded!'); };
document.getElementsByTagName('body')[0].appendChild(iframe);

Dies funktioniert wie erwartet, wenn ich es jedoch in addEventListener ändere, wird es nicht einmal zum DOM hinzugefügt:

var iframe = document.createElement('iframe');
iframe.addEventListener('load', function() { console.log('loaded!'); });
document.getElementsByTagName('body')[0].appendChild(iframe);

Ich habe attachEvent nicht im IE getestet.

Hat jemand etwas Licht ins Dunkel gebracht?

19
roryf

addEventListener() function benötigt 3 Argumente! Werfen Sie einen Blick auf https://developer.mozilla.org/de/DOM/element.addEventListener

Das dritte Argument ist als optional markiert, aber dann schreiben sie:

Beachten Sie, dass dieser Parameter nicht in allen Browser-Versionen optional ist.

Ich bin nicht sicher, wann und wo es erforderlich ist, aber meine Tests mit FF4 haben beim Aufruf der Variable addEventListener eine Ausnahme mit zwei Argumenten ausgelöst:

ausnahme nicht erfasst: [Ausnahme ... "Nicht genug Argumente" nsresult: "0x80570001 (NS_ERROR_XPC_NOT_ENOUGH_ARGS)" location: "JS-Frame: http: //localhost/index.php :: :: Zeile 10 "data: no]

Ihr Code funktioniert übrigens gut in Chrome [der String loaded! ist in der Konsole angemeldet].

Wie FF benötigt IE9 das dritte Argument im Standardmodus (mit <!DOCTYPE html>). IE9 ist das erste IE, das das Ereignismodell von W3C unterstützt. In den früheren Versionen müssen wir also attachEvent ausprobieren. Ich habe keine früheren IEs, aber es hat im IE7/8-Standardmodus und sogar im Quirks-Modus in IE9 funktioniert. Hier ist der Code, den ich verwendet habe:

<!DOCTYPE html>
<html>
<head><title></title></head>
<body>
<script>
    window.onload=function(){
        var iframe = document.createElement('iframe');
        var func = function() { console.log('loaded!');};
        if(iframe.addEventListener)
            iframe.addEventListener('load', func, true);
        else if(iframe.attachEvent)
            iframe.attachEvent('onload',func);
        document.body.appendChild(iframe);
    }
</script>
</body>
</html>
19

Das funktioniert für mich:

html:

iframe source code: <br />
<textarea id="output" rows="20" cols="60">loading ...</textarea>

javascript (auf documentReady):

var iframe = document.createElement('iframe');
iframe.id = iframe.name = "testframe";
iframe.src = "http://fiddle.jshell.net";
iframe.width = 400;
iframe.height = 100;
iframe.style.display = "none";

if (iframe.addEventListener)
    iframe.addEventListener("load", loaded, false);
else
    iframe.attachEvent("onload", loaded);

function loaded() {
    var html;
    if (iframe.contentDocument)
        html = iframe.contentDocument.getElementsByTagName("HTML")[0].innerHTML;
    else
        html = window.frames[iframe.name].document.getElementsByTagName("html")[0].innerHTML;

    document.getElementById("output").value = html;
}

document.getElementsByTagName("body")[0].appendChild(iframe);

Siehe die Demo unter: http://jsfiddle.net/WcKEz/

Funktioniert mit addEventListener, enthält jedoch den Fallback zu attachEvent. Zugriff auf das DOM des IFRAME natürlich nur auf derselben Domain.

1
roberkules

Funktioniert das erste Beispiel? Sie wissen nicht genau, wonach Sie suchen, dies sollte jedoch angezeigt werden, wenn Ereignisse funktionieren: jQuery document.ready source

$ (Dokument) .im Äquivalent ohne jQuery

addEventListener funktioniert nicht im IE. Wenn Sie also dort testen, schlägt der zweite fehl, bevor der iframe angehängt wird.

Sie können auch einen Rückruf von der Seite selbst hinzufügen. Allerdings würde ich vermuten, dass $(iframe).ready() {..} Ihnen konsistentes Verhalten verleiht (wenn Sie beispielsweise jQuery verwenden, um das Rad nicht neu zu erfinden).

0
Jamie Treworgy