Нужна ли 'onload', когда код находится внизу? - PullRequest
6 голосов
/ 03 января 2012

Мне было интересно, необходим ли window.onload = function(){} (или любой другой тип загрузки, например, jQuery $(document).ready();, если код находится в нижней части моего <body>?

Или там может бытьбыть очень неожиданные побочные эффекты?

Ответы [ 3 ]

7 голосов
/ 03 января 2012

Да, могут быть неожиданные последствия.Но нет, это не абсолютно необходимо.Время может быть отключено для вещей, которые все еще загружаются, таких как сложные макеты, глубокие структуры DOM, динамический HTML из других скриптов или изображения.Чтобы избежать таких ситуаций, всегда безопаснее обернуть ваш сценарий в событие onload.

Вот несколько примеров, демонстрирующих это.Все примеры, протестированные на Chrome 17.0.963.12 dev на OS X. Результаты работы браузера могут отличаться, если не используется onload, что демонстрирует его непредсказуемое поведение.Примеры возвращают fail, если результат отличается от ожидаемого (т. Е. Того, что указано в вашем дизайне), и возвращает success, когда результат соответствует ожидаемому.С onload они всегда возвращают success.

Пример 1

В этом примере код ожидает, что изображение будет определенной ширины.Если код обернут в событие onload, ширина верна, в противном случае это не так.

Демонстрация: http://jsfiddle.net/ThinkingStiff/qUWxX/

HTML:

<div id="result"></div>
<img id='image' src="http://thinkingstiff.com/images/matt.jpg" />

Скрипт:

document.getElementById( 'result' ).innerHTML 
    = document.getElementById( 'image' ).offsetWidth == 346 ? 'success': 'fail';

Вы увидите, что jsFiddle имеет значение "onLoad" в верхнем левом углу страницы, а результат над изображением - success.

enter image description here

Измените это на «onDomReady» или «без переноса (тело)»:

enter image description hereenter image description here

Теперь нажмите «Выполнить» в верхнем левом углустраница:

enter image description here

Результат над изображением теперь будет fail.

Пример 2

Вот еще один пример, который нет использовать изображения.В этом встроенный скрипт был добавлен в HTML.Код ожидает, что ширина будет такой, какой он был установлен встроенным скриптом.С onload это corrent, без, это не так.Для этой демонстрации используйте те же инструкции, что и раньше.

Демо: http://jsfiddle.net/ThinkingStiff/n7GWt/

HTML:

<div id="result"></div>
<div id="style"></div>

<script>
    window.setTimeout( function() { 
        document.getElementById( 'style' ).style.width = '100px'; 
    }, 1 );
</script>

Сценарий:

document.getElementById( 'result' ).innerHTML 
    = document.getElementById( 'style' ).style.width ? 'success' : 'fail';

Пример3

Вот пример, который не использует изображения или JavaScript в теле, только CSS.Опять же, результаты различаются между onload и не.

Демонстрация: http://jsfiddle.net/ThinkingStiff/HN2bH/

CSS:

#style {
    animation:             style 5s infinite;
        -moz-animation:    style 5s infinite;
        -ms-animation:     style 5s infinite;
        -o-animation:      style 5s infinite;
        -webkit-animation: style 5s infinite;
    border: 1px solid black;
    height: 20px;
    width: 100px;    
}

@keyframes             style { 0% { width: 100px; } 100% { width: 500px; } }
    @-moz-keyframes    style { 0% { width: 100px; } 100% { width: 500px; } }
    @-ms-keyframes     style { 0% { width: 100px; } 100% { width: 500px; } }
    @-o-keyframes      style { 0% { width: 100px; } 100% { width: 500px; } }
    @-webkit-keyframes style { 0% { width: 100px; } 100% { width: 500px; } }

HTML:

<div id="result"></div>
<div id="style"></div>

Сценарий:

document.getElementById( 'result' ).innerHTML 
    = document.getElementById( 'style' ).clientWidth > 100 ? 'success' : 'fail';

Существует слишком много сценариев, в которых отсутствие переноса кода может вызвать проблемы, которые вы не сможете предвидеть.Чтобы избежать таких ситуаций, всегда безопаснее заключить сценарий в событие onload.

2 голосов
/ 03 января 2012

Пара разных вещей происходит.

  1. onload вызывается только после загрузки встроенного содержимого, такого как изображения.Это означает, что вы можете поместить код в onload, который зависит от того, что там находится.
  2. готовые обработчики запускаются до этого, когда DOM (то есть внутренняя структура) вашей страницы полностью загружен.Это не , что отличается от того, чтобы поместить его внизу, но одно отличие состоит в том, что если кто-то уйдет от вашей страницы, а затем обратно, эти обработчики сработают снова.Технически сценарии, которые выполняются в конце документа, могут использовать такие методы, как getElementById, для извлечения уже визуализированных элементов.Возможно, вы захотите поместить их в обработчик готовности или загрузки по указанным выше причинам.Это не значит, что сами сценарии не должны быть внизу - все же есть преимущество в воспринимаемой производительности от их наличия.
1 голос
/ 03 января 2012

Тег скрипта внизу HTML-страницы эквивалентен DOMContentLoaded. Весь HTML-код был загружен, и теперь Javascript способен обращаться к элементам DOM.

load вызывается, когда все другие ресурсы, такие как изображения, полностью загружены.

...