Почему упорядочение скриптов важно при назначении функции window.onload? - PullRequest
3 голосов
/ 12 марта 2012

У меня есть веб-сайт с тремя файлами:

index.html

<html>
<head>
<script src="First.js"></script>
<script src="Second.js"></script>
</head>
<body></body>
</html>

First.js

window.onload = Main;

Second.js

function Main() { var foo = 1; }

Когда я открываю страницу, я ожидаю, что переменная 'foo' будет установлена ​​в '1'.Вместо этого, когда я открываю страницу, она разрывается, указывая, что «Main не определен» * и «Main ()» никогда не вызывается.

Если событие «.onload» для окна нене должен запускаться до тех пор, пока страница не будет полностью загружена и, следовательно, предполагается, что оба сценария были загружены, почему объект окна не имеет ссылки на метод Main () в Second.js?Должна ли функция Main () быть общедоступной функцией?

ПРИМЕЧАНИЕ. Я понимаю, что могу изменить порядок загрузки сценариев, и тогда мой код будет работать, но это не является целью моего вопроса.Что я действительно хочу сделать, так это подтвердить мое предположение.

Ответы [ 3 ]

2 голосов
/ 12 марта 2012

Второй файл скрипта должен быть включен первым!Вот где определяется функция.Вы не можете ссылаться на него в первом скрипте, пока он не загружен.

2 голосов
/ 12 марта 2012

Не работает, потому что код в элементах <script> выполняется последовательно и независимо (по умолчанию предполагается синхронные сценарии). То есть две разные <script> секции не могут напрямую ссылаться друг на друга. Теперь JavaScript "поднимает" function name () {} конструкции в том же контексте , так что это сработало бы "не по порядку" в одном <script>.

Преамбула / предупреждение:

Рассмотрим , а не , используя onload. Если что-то еще попытается использовать (onload), то что-то, скорее всего, сломается. (Я рекомендую jQuery, потому что он «понимает это правильно» и «чертовски легко» ... опять же, так делают многие другие фреймворки. Выберите один: -)

Например, это будет работать в jQuery:

jQuery(function () { Main() })

Объяснение того, почему это работает (и как это исправить, не переупорядочивая скрипты или используя jQuery):

Обратите внимание, что в этом случае вызывается внутренний обработчик событий jQuery, который вызывает анонимный обратный вызов, который затем вызывает Main (который теперь преобразуется в объект-функцию). «Подобный» код здесь будет:

window.onload = function () { Main() }

Они работают, потому что Main является , не оценивается до тех пор, пока не будет загружено , и в этом случае все элементы [синхронный] <script> были выполнены. (Пожалуйста, смотрите мой комментарий относительно того, что означает оценка Main.)

С другой стороны, window.onload = Main (или jQuery(Main)) оцените Main прямо тогда и используйте полученное значение; как уже отмечали другие, Main не установлено («не определено») на этом этапе из-за упорядочения элементов <script> (они запускаются последовательно).

Пожалуйста, обратитесь к примечанию вверху о том, почему не , чтобы использовать onload напрямую; -)

Счастливого кодирования.

1 голос
/ 12 марта 2012

Функция Main() не существует до тех пор, пока не будет загружен Second.js, поэтому, если вы сначала загружаете First.js, в window.onload = Main; нет объекта-функции для использования (Main не определено). Сначала загрузите Second.js, если вы этого еще не сделали.

...