Iframe поведение onload vs addEventListener ('load')
Я играл с добавлением скрытых элементов 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.
Кто-нибудь проливает свет на это?
Ответы
Ответ 1
addEventListener()
функция требует 3 аргумента! Взгляните на https://developer.mozilla.org/en/DOM/element.addEventListener
Третий аргумент помечен как необязательный, но затем они пишут:
Обратите внимание, что этот параметр не необязательно во всех версиях браузера.
Я не уверен, когда и где это необходимо, но мои тесты на FF4 вызывают исключение при вызове addEventListener
с двумя аргументами:
исключение uncaught: [Exception... "Not достаточно аргументов" nsresult: "0x80570001 (NS_ERROR_XPC_NOT_ENOUGH_ARGS)" местоположение: "JS frame:: http://localhost/index.php:: :: строка 10 ": нет]
Кстати, ваш код хорошо работает в Chrome [строка loaded!
зарегистрирована в консоли].
Подобно FF, IE9 нуждается в третьем аргументе в стандартном режиме (с <!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>
Ответ 2
Это работает для меня:
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, конечно, только в том же домене.
Ответ 3
Работает ли первый пример? Не уверен, что именно вы ищете, но это должно освещаться при работе событий: источник jQuery document.ready
$(document).ready эквивалент без jQuery
addEventListener не работает в IE, поэтому, если вы тестируете, то второй будет терпеть неудачу до добавления iframe.
Вы также можете добавить обратный вызов из самой страницы (например, используя jQuery, чтобы вы не изобретали колесо). Я подозреваю, что $(iframe).ready() {..}
даст вам последовательное поведение.