Ну что ж, немного отвлечемся от программирования по расписанию (ха!). Пока что весь написанный нами код в полном объеме «жил» внутри HTML-документа:
body {
background-color: #EEE;
}
h1 {
font-family: sans-serif;
font-size: 36px;
}
p {
font-family: sans-serif;
}
Are you ready for this?
Are you ready for seeing (or already having seen!) the most
amazing dialog ever?
alert("hello, world!");
Попробуем отмотать немного назад и поразмыслить вот над чем: целесообразно ли использовать элементы HTML, CSS и JS в одном документе? Для простоты нашего толкования структуры документа попробуем прибегнуть к творческому подходу и изменить представление кода, например отобразив его в виде таких вот чудных рамок (рис. 10.1):
Рис. 10.1. Наше представление веб-страницы
В примере ниже HTML-документ отделен от JavaScript лишь парой тегов script. Но на самом деле JavaScript-код не обязательно селить внутри HTML-документа. Его можно написать в отдельном файле (рис. 10.2).
При этом подходе мы больше не пишем JavaScript-код в HTML-документе. У нас по-прежнему есть тег script, но он лишь указывает на файл JavaScript, а не содержит все строки его кода.
Рис. 10.2. Теперь код JS живет в своем собственном файле!
Стоит заметить, что оба подхода не исключают друг друга, то есть мы можем совмещать их в документе HTML, применяя гибридный подход, при котором у нас будут как внешний файл JavaScript, так и строки JS-кода, содержащиеся внутри документа (рис. 10.3).
Рис. 10.3. Смешанный подход, при котором код JS существует в нескольких местах
Что еще интереснее, так это то, что у каждого из этих подходов могут быть свои дополнительные вариации. Например, создание нескольких секций script в HTML-документе или нескольких JS-файлов и т. д. В последующих разделах мы рассмотрим подробнее оба подхода и обсудим, когда и какой из них лучше выбирать.
В конце у вас сложится представление обо всех плюсах и минусах, что позволит вам грамотно взаимодействовать с JavaScript при разработке веб-страниц и приложений.
Поехали!
Подход № 1: весь код в HTML-документе
Первым мы рассмотрим подход, который использовали все это время. Он предполагает, что весь код JS находится внутри тега script рядом с остальной частью HTML-документа:
Example
function showDistance(speed, time) {
alert(speed * time);
}
showDistance(10, 5);
showDistance(85, 1.5);
showDistance(12, 9);
showDistance(42, 21);
Когда ваш браузер загружает страницу, он поочередно считывает каждую строку кода в HTML-документе сверху вниз. Дойдя до тега script, он также обрабатывает все строки JavaScript-кода. Закончив выполнение, он продолжает считывать оставшуюся часть документа. Это значит, что местоположение тега script очень важно. Мы обсудим этот момент чуть позже, при рассмотрении темы выполнения кода в подходящее время.
Подход № 2: код существует в отдельном файле
В этом случае наш основной HTML-документ не содержит никакого JS-кода. Вместо этого весь код располагается в отдельном документе. Такой подход разделен на две части. Первая относится к самому файлу JavaScript, а вторая отвечает за связь этого файла с HTML. Давайте рассмотрим обе эти части подробнее.
JS-файл
Основой описываемого подхода является отдельный файл, содержащий код JavaScript. Не имеет значения, как вы назовете этот файл, но его расширение, как правило, будет. js. Например, мой файл JS назван example.js.
Внутри этого файла будет размещен только JavaScript:
function showDistance(speed, time) {
alert(speed * time);
}
showDistance(10, 5);
showDistance(85, 1.5);
showDistance(12, 9);
showDistance(42, 21);
Все, что мы обычно поместили бы в тег script, попадет сюда. Кроме этого, мы не будем ничего добавлять, так как появление в этом файле других элементов вроде произвольно выбранных частей HTML и CSS не допускается, а в ответ на подобные действия браузер заругается.
Ссылка на JavaScript-файл
Как только мы создали файл JS, второй (и заключительный) шаг — это связать его со страницей HTML. За это отвечает тег script, а конкретнее — его атрибут src, который указывает на расположение JavaScript-файла:
Example
В этом примере, если файл JavaScript расположен в одном каталоге с HTML, мы можем использовать относительный путь и сослаться напрямую на имя файла. А если этот файл находится в другом каталоге, нам нужно будет соответственно изменить путь:
Example
В этом случае наш файл сценария вложен в три уровня каталогов с именами some, other и folder. Кроме того, мы также можем прибегнуть к использованию абсолютного пути вместо относительного:
Example
Не важно, если пути относительные или абсолютные, — они будут прекрасно работать. В ситуациях же, когда путь между HTML-страницей и сценарием, на который мы ссылаемся, отличается (например, внутри шаблона, серверного включения, сторонней библиотеки и т. д.), безопаснее использовать абсолютный путь.
Итак, какой подход использовать?
У нас есть два основных подхода, определяющих, как и где следует размещать код (рис. 10.4).
Рис. 10.4. Два основных подхода, используемых для работы с кодом JavaScript
Конечный выбор подхода зависит от ответа на следующий вопрос: «Планируется ли использование одного и того же кода в нескольких HTML-документах?»
Считывание и расположение сценариев в документе
Несколькими разделами ранее я описывал выполнения сценариев. Браузер считывает HTML-страницу, начиная сверху и построчно перемещаясь вниз. Когда он достигает тега script, то начинает выполнять содержащийся в нем код. Это выполнение также происходит построчно, начинаясь с верхней части. Все остальные возможные действия страницы на время этого выполнения приостанавливаются. Если тег script ссылается на внешний JS-файл, то прежде, чем начать выполнение этого файла, браузер его загрузит.
При таком линейном считывании документа браузером наблюдается интересные нюансы, влияющие на то, где лучше размещать теги script. Технически их можно разместить в любой части HTML-документа. Тем не менее для этого есть предпочтительное место. Учитывая то, как браузер считывает страницу, и то, что он все блокирует во время выполнения сценариев, следует размещать теги script в нижней части HTML-документа, после всех его элементов.
Если тег script окажется в верхней части документа, то на время его выполнения браузер заблокирует все остальное. В результате если вы начнете загружать большой файл сценария или будете выполнять сценарий, то пользователь сможет увидеть частично загруженную и не отвечающую HTML страницу. До тех пор пока у вас не возникнет реальной потребности в выполнении JavaScript до полного считывания документа, размещайте теги script в конце, как показано в большинстве предыдущих примеров. Есть и еще одно преимущество в расположении скриптов внизу страницы, но о нем я расскажу значительно позднее, когда мы будем говорить о DOM (объектная модель документа) и о том, что происходит в процессе загрузки страницы.
Да, мой код будет использоваться в нескольких документах!
Если ответ да, тогда наверняка лучше будет поместить код в отдельный файл и сделать на него ссылку во всех HTML-страницах, которые должны его выполнять. Первая причина, по которой это стоит сделать, — вы сможете избежать повторения кода на всех этих страницах (рис. 10.5).
Рис. 10.5. Повторение кода — это проблема!
Сопровождение повторяющегося кода — это кошмар, при котором изменение сценария потребует внесения изменений в каждый HTML-документ. Если вы используете некий шаблон или логику SSI, где ваш сценарий содержится только в одном HTML-фрагменте, тогда проблема сопровождения окажется не столь велика.
Вторая причина заключается в размере файла. Если вы дублируете сценарий во множестве HTML-страниц, то каждый раз, когда пользователь загружает одну из этих страниц, он заново загружает весь сценарий. Это не такая уж и проблема, когда речь идет о небольших сценариях, но, как только в коде появляется нескольких сотен строк, размер начинает существенно расти.
Если вы размещаете весь код в одном файле, то все только что упомянутые проблемы у вас уже не возникнут (рис. 10.6).
Рис. 10.6. Весь код в одном месте
Сопровождение кода облегчается, так как его обновление производится только в одном файле. Любой HTML-документ, ссылающийся на этот JS-файл, при загрузке автоматически получает его последнюю версию. Это также позволит браузеру загружать код всего один раз и предоставлять его сохраненную в кэше версию для последующих обращений.
Нет, мой код используется только в одном HTML-документе
Если ваш ответ нет, то можете поступать по своему усмотрению. Вы по-прежнему можете разместить код в отдельном файле и сослаться на него из HTML-документа, но это принесет меньше выгоды, чем в случае с несколькими документами, который мы рассмотрели ранее.
В такой ситуации вполне подойдет размещение всего кода полностью в HTML-файле. В этом аспекте код из большинства примеров написан внутри HTML-документа. Примеры рассматриваемых кодов не предполагают их использования для множественных страниц и также большие размеры, при которых для повышения читаемости может потребоваться размещение кода в отдельном файле.
КОРОТКО О ГЛАВНОМ
Теперь вы увидели, что решение даже такого простого вопроса, как размещение кода, требует многостраничных объяснений. Добро пожаловать в мир HTML и JavaScript, где нет четкого деления на то, что такое хорошо и что такое плохо. Возвращаясь к сути этого урока, стоит отметить, что типичный HTML-документ будет содержать много файлов сценариев, загружаемых из внешних источников. Некоторые из этих файлов будут вашими, некоторые же будут взяты из сторонних ресурсов.
Напомню и о смешанном подходе, когда в вашем HTML-документе содержится не только ссылка на отдельный JS-файл, но и сам JS-код. Такой подход тоже достаточно распространен. В конце концов, только вам решать, какой именно подход использовать. Надеюсь, что эта глава предоставила вам достаточно информации, чтобы вы могли выбирать подходы осознанно. В главе 35 «События загрузки страницы и прочее» мы еще больше углубимся в пройденную в этой главе тему, рассмотрев на примерах связанные с загрузкой страниц и некоторые особые атрибуты, которые привносят в этот процесс свои сложности. Но пока не будем о них думать.
Если у вас появились вопросы, уверенно задавайте их на форуме https://forum.kirupa.com. Я и другие разработчики будем рады вам помочь!