jQuery: зачем использовать document.ready, если внешний JS внизу страницы?

88

Я включаю все свои JS как внешние файлы, которые загружаются в самом низу страницы. В этих файлах у меня есть несколько таких методов, которые я вызываю из события готовности:

var SomeNamepsace = {};

SomeNamepsace.firstMethod = function () {
    // do something
};

SomeNamepsace.secondMethod = function () {
    // do something else
};

$(document).ready(function () {
    SomeNamepsace.firstMethod();
    SomeNamepsace.secondMethod();
});

Однако, когда я удаляю функцию ready и вызываю методы напрямую, все работает точно так же, но выполняется значительно быстрее - почти на целую секунду быстрее в довольно простом файле! Поскольку документ должен быть загружен в этот момент (поскольку вся разметка идет перед тегами скрипта), есть ли веские причины для использования события ready?

беспокойный дизайн
источник
9
Интересный вопрос. К сожалению, текущие ответы на самом деле не отвечают на этот вопрос, и у меня тоже нет хороших ответов. Возможно, стоит перефразировать вопрос следующим образом: «помещает документы JavaScript в конец файла, гарантируя, что DOM загружается перед выполнением»
Борис Калленс

Ответы:

116

Отличный вопрос.

Существует некоторая путаница вокруг всего совета «размещать скрипты внизу страницы» и того, какие проблемы он пытается решить. В этом вопросе я не буду говорить о том, влияет ли размещение скриптов внизу страницы на производительность / время загрузки или нет. Я расскажу только о том, нужны ли вам, $(document).ready если вы также разместите скрипты внизу страницы .

Я предполагаю, что вы ссылаетесь на DOM в тех функциях, которые немедленно вызываете в своих сценариях (что угодно, например, documentили document.getElementById). Я также предполагаю, что вы спрашиваете только об этих файлах [ссылки на DOM]. IOW, скрипты библиотеки или скрипты, которые требует ваш код, ссылающийся на DOM (например, jQuery), должны быть размещены на странице раньше.

Чтобы ответить на ваш вопрос : если вы включите свои сценарии, ссылающиеся на DOM, внизу страницы, нет, вам не нужно $(document).ready.

Объяснение : без помощи "onload"связанных реализаций, например, практическое $(document).readyправило: любой код, который взаимодействует с элементами DOM на странице, следует размещать / включать дальше вниз по странице, чем элементы, на которые он ссылается. Проще всего разместить этот код перед закрытием </body>. Смотрите здесь и здесь . Он также работает с ужасной ошибкой IE «Операция прервана» .

Сказав это, это ни в коем случае не отменяет использование $(document).ready. Ссылка на объект до того, как он был загружен, является [одной из] наиболее распространенных ошибок, которые допускаются при запуске в DOM JavaScript (слишком много раз наблюдали это, чтобы сосчитать). Это решение проблемы с помощью jQuery, и вам не нужно думать о том, где этот сценарий будет включен относительно элементов DOM, на которые он ссылается. Это огромная победа для разработчиков. Им нужно думать только на одну вещь меньше.

Кроме того, часто бывает сложно или непрактично переместить все сценарии, ссылающиеся на DOM, в нижнюю часть страницы (например, любой сценарий, document.writeвызывающий вызовы, должен оставаться на месте). В других случаях вы используете фреймворк, который отображает какой-либо шаблон или создает фрагменты динамического javascript, в котором ссылаются на функции, которые необходимо включить до js.

Наконец, раньше было «лучшей практикой» втиснуть в него весь код, ссылающийся на DOM window.onload, однако его затмили $(document).readyреализации по причинам, связанным с хорошей документацией .

Все это составляет $(document).readyгораздо более совершенное, практичное и общее решение проблемы слишком раннего обращения к элементам DOM.

Crescent Fresh
источник
5
«если вы включите свои сценарии, ссылающиеся на DOM, внизу страницы, нет, вам не нужен $ (document) .ready». Игнорируя проблему document.write, которую вы решите позже в своем сообщении, этот ответ делает наивное предположение весь CSS загружается и обрабатывается до запуска javascript. Это может быть неправдой; браузеры могут загружать внешние файлы параллельно.
Powerlord
8
не совсем правильно, если у вас есть deferготовый документ сценария, он будет гарантировать, что они выполняются до готового кода. см .: w3.org/TR/html5/the-end.html#the-end
Sam Saffron,