iframe поведение onload против addEventListener ('загрузка') - PullRequest
19 голосов
/ 07 марта 2011

Я играл с добавлением скрытых элементов iframe на страницу, и я хочу манипулировать DOM из этих когда-то загруженных. Я заметил, что не могу начать манипулировать DOM сразу после добавления iframe на страницу, так как он еще не загружен. Это невозможно сделать с событием DOMContentLoaded, поскольку оно запускается для документа, которого нет в iframe, пока он не будет добавлен на страницу, поэтому мы должны использовать событие load.

Вот код теста:

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

Это работает, как и ожидалось, однако, когда я изменяю его на addEventListener, оно даже не добавляется в DOM:

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

Я не проверял attachEvent в IE.

Кто-нибудь пролил свет на это?

Ответы [ 3 ]

19 голосов
/ 23 мая 2011

addEventListener() функция требует 3 аргумента! Взгляните на https://developer.mozilla.org/en/DOM/element.addEventListener

Третий аргумент помечается как необязательный, но затем пишется:

Обратите внимание, что этот параметр не необязательно во всех версиях браузера.

Я не уверен, когда и где это требуется, но мои тесты на FF4 вызвали исключение при вызове addEventListener с 2 аргументами:

необученное исключение: [Исключение ... "Не хватит аргументов «0x80570001 (NS_ERROR_XPC_NOT_ENOUGH_ARGS)» расположение: "JS frame :: http://localhost/index.php :: :: строка 10 "данные: нет]

Кстати, ваш код хорошо работает в Chrome [строка loaded! зарегистрирована в консоли].

Как и FF, IE9 нуждается в 3-м аргументе в стандартном режиме (с <!DOCTYPE html>). IE9 - первый IE, который поддерживает модель событий W3C. Так что в более ранних версиях нам нужно попробовать attachEvent. У меня нет более ранних версий IE, но он работал в режиме стандартов IE7 / 8 и даже в режиме Quirks в IE9. Вот код, который я использовал:

<!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>
1 голос
/ 23 мая 2011

Это работает для меня:

html:

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

javascript (on 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);

См. Демонстрацию по адресу: http://jsfiddle.net/WcKEz/

Работает с addEventListener, но включает откат к attachEvent.Доступ к DOM IFRAME, конечно, только в том же домене.

0 голосов
/ 07 марта 2011

Первый пример работает? Не уверен, что именно вы ищете, но это должно подсвечиваться, когда работают события: jQuery document.ready source

$ (документ). Уже эквивалентен без jQuery

addEventListener не работает в IE, поэтому, если вы тестируете его, то 2-й сбой до того, как будет добавлен iframe.

Вы также можете добавить обратный вызов со страницы, хотя (например, используя jQuery, чтобы не изобретать велосипед), я подозреваю, $(iframe).ready() {..} даст вам согласованное поведение.

...