Язык JavaScript и сценарии
В этой главе:
В этой части книги рассматривается ядро языка JavaScript в соответствии со спецификацией 1.5 оригинальной версии языка (разработанной Sun и Netscape) и с третьей редакцией международного стандарта ECMA-262 (ECMAScript), а так же взаимодействие с объектами HTML, поддерживаемое всеми рассматриваемыми браузерами. Причем такое взаимодействие также стандартизировано в рамках DOM – объектной модели документа (Document Object Model).
Собственно говоря, для разработчика web-страниц, в первую очередь, ценен не сам по себе язык JavaScript, а именно его возможности по взаимодействие с документом. Более того, взаимодействовать с документом, в принципе, может любой язык – была бы только его поддержка со стороны программы просмотра – так, для сценариев в MSIE можно использовать язык VBScript. Но поскольку, не зная языка, невозможно создавать программы (сценарии) взаимодействия с документом, то начнем мы как раз с изучения языка JavaScript как такового.
Java и JavaScript
Перед тем, как приступить к изучению JavaScript, следует сказать пару слов об этом языке. Прежде всего, не следует путать его с языком Java. Последний является полнофункциональным и универсальным языком программирования – таким, как C или Pascal. Его разработкой занимается компания Sun, а предназначен он, в первую очередь, для написания самостоятельных программ. Что же касается JavaScript, то это – специализированный язык для создания сценариев на страницах Web, изначально разработанный Netscape и называвшийся LiveScript. Впоследствии язык был доработан в сотрудничестве с той же Sun, в результате чего и получил свое современное название – JavaScript, и именно с таким именем он впервые появился в далеком 1995 году в составе браузера Netscape 2.
В отличие от Java, JavaScript не претендует на то, чтобы стать универсальным языком программирования – он развивается в ином направлении. В частности, постоянно улучшается взаимодействие JavaScript и HTML, реализуемое через DOM. Параллельно с этим, языки разметки так же были модернизированы с целью обеспечения более гибкого взаимодействия с DOM, и, в конечном итоге – со сценариями JavaScript. Так, начиная с HTML 4.0, практически для каждого элемента определены атрибуты, которые предназначены для определения обработчиков событий. С другой стороны, все эти события могут быть перехвачены и обработаны непосредственно сценарием.
ПРИМЕЧАНИЕ
Надо отметить, что JavaScript имеет средства для взаимодействия с апплетами Java: к классам Java-программы можно напрямую обращаться из сценариев JavaScript. Делается это при помощи системы LiveConnect, впервые примененной в Netscape 3.0. Но возможность обращаться к классам Java является фирменной технологией Netscape, и не поддерживается в MSIE и в других браузерах. В то же время, сегодня для этих же целей применяется JRE.
Различия между языками Java и JavaScript касаются также и способов представления программы. Так, программы Java должны компилироваться в платформенно-независимый байт-код, который затем выполняется при помощи виртуальной Java-машины (Java VM). Для этого у разработчика программ на Java должно быть установлено специальное программное обеспечение, например, Java SDK фирмы Sun Microsystems, а у пользователя – Java VM или JRE. Соответственно, если речь идет об Java-апплетах (специальных программах для выполнения в браузере), то браузер задействует Java VM для преобразования байт-кода в исполняемый код, после чего внедряет на страницу Java-апплет в качестве объекта. В то же время, программы JavaScript «доходят» до браузера в виде исходного текста, чтобы затем быть выполненными встроенным в браузер интерпретатором. Соответственно, никакого дополнительного программного обеспечения авторам сценариев на JavaScript не требуется, а сам сценарий выполняется браузером без привлечения дополнительных внешних средств.
JavaScript и DOM
Как уже было отмечено, язык JavaScript для web-мастера ценен, прежде всего, тем, что позволяет взаимодействовать с объектной моделью документа. Базовые основы DOM были заложены еще в первый браузер, поддерживающий сценарии, т.е. в Netscape 2, и получили свое развитие в Netscape 3. При этом явно никакого стандарта на тот момент не было, и уже впоследствии, на основе того, что «умел делать» Netscape 3 (и, отчасти, MSIE 3), была разработана первая спецификация, получившая название DOM уровня 0. Число 0 было выбрано не случайно, поскольку фактически никакой целостной объектной модели документа в ней не обеспечивалось.
После выхода черновой спецификации DOM 0, началась разработка стандарта первой полноценной модели документа, получившей название DOM уровня 1. Первым браузером, хотя бы в целом поддерживающим DOM 1, был MSIE 4.0, в то время как Netscape 4 получил лишь расширения для DOM 0.
ПРИМЕЧАНИЕ
Здесь, справедливости ради, следует отметить, что даже первая черновая спецификация DOM 1 появилась уже после того, как появился Netscape 4.0. Что же касается, MSIE 4.0, то он так же вышел значительно раньше, чем спецификация DOM 1 приняла свой окончательный вид. Именно по этой причине долгое время были большие проблемы с совместимостью JavaScript-кода.
Итак, что же такое DOM? Это – прикладной интерфейс (API) для HTML и XML-документов, определяющий их логическую структуру и способы для взаимодействия. Используя DOM, разработчики могут создавать документы, перемещаться по их структуре, добавлять, удалять и изменять элементы и их содержимое.
Фактически, объектная модель представляет документ логически в качестве древовидной структуры. Например, если взять в качестве основы для конкретной модели приведенную ниже таблицу, то она получит собственное представление в виде иерархической древовидной структуры (рис. 4.1):
<table>
<tbody>
<tr>
<td>Текст ячейки 1</td>
<td>Текст ячейки 2</td>
</tr>
<tr>
<td>Текст ячейки 3</td>
<td>Текст ячейки 4</td>
</tr>
</tbody>
</table>

Рис. 4.1. Представление таблицы размером 2x2 ячейки в виде дерева DOM
Для того чтобы иметь возможность наглядно исследовать объектную модель любого документа, в некоторых браузерах (точнее сказать, во всех современных вариантах Mozilla) имеется специальное средство – инспектор DOM (рис. 4.2). Правда, с некоторых пор он не входит в стандартную поставку Firefox, но имеется в SeaMonkey. Так же его можно установить в виде расширения (DOM Inspector - https://addons.mozilla.org/ru/firefox/addon/dom-inspector-6622/). После установки в меню «Веб-разработка» появится пункт «Инспектор DOM».

Рис. 4.2. Инспектор DOM в Mozilla Firefox
При помощи инспектора DOM можно просмотреть структуру документа, полученную в результате его интерпретации браузером, получить информацию о значениях атрибутов элементов, а так же исследовать все свойства, назначенные каждому конкретному элементу в качестве объекта JavaScript.
Мы еще вернемся к детальному изучению объектной модели в этой части книги, но уже после того, как ознакомимся с основами собственно языка JavaScript.
Внедрение сценариев в документы HTML
Главным достоинством JavaScript является не только его приспособленность для нужд HTML и взаимодействия с DOM, но также и легкость внедрения скриптов в документы. Для этих целей в HTML предусмотрен элемент SCRIPT. Он достаточно подробно описывается во второй части этой книги, здесь же мы рассмотрим варианты расположения сценариев внутри страниц.
Итак, скрипты могут находиться в любом месте HTML-документа, к примеру, в части HEAD, или внутри любого контейнера в BODY. Кроме того, можно включать сценарии непосредственно внутрь тегов – в качестве значений для атрибутов обработки событий (ONCLICK, ONMOUSEOVER и т.д.). Однако теги HTML нельзя помещать внутри программы JavaScript, кроме как внутри строковых переменных.
Различие между сценарием, помещенным в часть HEAD документа и сценарием в части BODY сводится к тому, что первый будет загружен в память раньше, чем документ. Поэтому в части заголовка документа обычно размещают описания функций, а в теле – обращения к этим функциям, например, для формирования документа «на лету». Типичный пример – создание приветствия, изменяющегося со временем суток, приведен в листинге 4.1.
Листинг 4.1. Размещение сценариев в заголовке и в теле документа
<head>
<script type="text/JavaScript"><!--
function gethello() {
var nowdate = new Date();
var nowtime = nowdate.getHours();
var hellostr = '';
if (nowtime>=0 && nowtime<6) {hellostr="Доброй ночи!";}
if (nowtime>=6 && nowtime<11) {hellostr="С добрым утром!";}
if (nowtime>=11 && nowtime<18) {hellostr="Добрый день!";}
if (nowtime>=18) {hellostr="Добрый вечер!";}
return hellostr;
}
//--></script>
</head>
<body>
<script type="text/JavaScript"><!--
document.write(gethello());
//--></script>
...
</body>
В этом примере в части HEAD определяется функция gethello(), которая, в зависимости от системного времени, возвращает строку с тем или иным приветствием. Сама функция вызывается уже из части BODY, где возвращаемое ей значение используется в качестве аргумента метода write. В результате после загрузки документа, в его начале, вместо контейнера SCRIPT будет находиться строка с приветствием.
Что касается сценариев, размещаемых в атрибутах HTML-элементов для обработки событий, то они, как правило, включают в себя либо вызовы заранее определенных функций, либо очень короткие сценарии:
<a href="#" onclick="alert('Привет!');">Щелкни здесь</a>
В данном случае, при щелчке по ссылке, вызывается метод alert, создающий модальное диалоговое окно с надписью «Привет!».
Помимо встраивания JavaScript-программ непосредственно в документ HTML существует возможность загружать их из отдельных файлов. Делается это при помощи атрибута SRC элемента SCRIPT. Например, для включения в документ сценария, расположенного в отдельном файле на удаленном сервере, используется такая конструкция:
<script src="http://host.ru/user5/hello.js" type="text/JavaScript"></script>
Здесь указывается, что скрипт должен быть загружен с сервера host.ru из файла hello.js, находящегося в каталоге user5. Следует также заметить, что файл .js может содержать только текст программы, и не должен включать в себя ни тегов SCRIPT, ни иных «инородных» для JavaScript конструкций. Иными словами, если вернуться к примеру их листинга 4.1, и модифицировать его таким образом, чтобы вынести определение функции gethello() за пределы HTML0-документа, то в части head следовало бы оставить такое определение элемента SCRIPT:
<script src="hello.js" type="text/JavaScript"></script>
При этом подразумевается, что файл сценария hello.js расположен в том же каталоге, что и HTML-документ, ссылающийся на него, а сам файл hello.js содержит только текст сценария и ничего больше:
function gethello() {
var nowdate = new Date();
var nowtime = nowdate.getHours();
var hellostr = '';
if (nowtime>=0 && nowtime<6) {hellostr="Доброй ночи!";}
if (nowtime>=6 && nowtime<11) {hellostr="С добрым утром!";}
if (nowtime>=11 && nowtime<18) {hellostr="Добрый день!";}
if (nowtime>=18) {hellostr="Добрый вечер!";}
return hellostr;
}
Вообще же вынесение сценариев JavaScript в отдельные файлы по своей сути аналогично вынесению таблиц стилей в файлы CSS: при этом достигается большая гибкость и возможность модернизации всего сайта путем правки единичного текстового документа.
Совместимость
Различные версии браузеров разных производителей поддерживают разные версии языка JavaScript. Поскольку, в отличие от HTML, JavaScript является языком программирования, то в отношении сценариев действуют куда более жесткие правила проверки синтаксиса. Так, если в HTML-документе вы укажите несуществующий тег или атрибут, он просто будет проигнорирован, в то время как обращение к несуществующему объекту или функции в JavaScript-программе приведет к ошибке и прервет ее выполнение. Эта проблема особенно актуальна из-за различий между браузерами.
Изо всех встречающихся на сегодняшний день браузеров, пожалуй, лучше всего с JavaScript работает Mozilla, что и не удивительно – все-таки это наследник браузера Netscape, прародителя самого языка JavaScript. В последнее время и все остальные браузеры так же обеспечивают поддержку сценариев JavaScript в надлежащем объеме, включая Chrome, MSIE и Opera. В таблице 4.1 приведена информация о соответствии различных версий языка JavaScript в реализации тех или иных браузерах.
Версия JavaScript | Браузеры | Примечания |
---|---|---|
01.01.00 | Netscape 2, MSIE 3 | - |
1.1/ECMA-262-e1 | Netscape 3, MSIE 4, Opera 4 | - |
01.02.11 | Netscape 4.0-4.05 | Не совместим со стандартом ECMA-262 |
1.3/ECMA-262-e2 | Netscape 4.06-4.8, Opera 7 | В целом поддерживается MSIE 5 и Opera 5 |
01.04.11 | Ранние beta-версии Mozilla | В окончательном виде стал версией 1.5 |
1.5/ECMA-262-e3 | Mozilla | В целом поддерживается MSIE 6-8 и Opera 7-11, а так же Chrome |
1.6/E3+E4X | Firefox 1.5 | Реализована поддержка XML |
01.07.11 | Firefox 2.0 | Введена поддержка генераторов в стиле Python |
01.08.11 | Firefox 3.0 | Введена поддержка замыканий (вид вложенной функции). Поддерживается в Opera 11.5 |
01.08.05 | Firefox 4.0 | Полная поддержка JSON. Совместим с ECMAScript 5. Поддерживается в MSIE 9. |
Из приведенной таблицы видно, что в общем современные браузеры имеют достаточно хорошую поддержку языка JavaScript, хотя и имеют различные нюансы с поддержкой тех или иных особенностей. Важно так же отметить, что для JavaScript поддерживается обратная совместимость, т.е. сценарий, написанный на JavaScript 1.5 будет выполняться браузером, поддерживающим JavaScript 1.8 (но не наоборот!).
Вместе с тем, хорошая поддержка самого языка JavaScript еще не означает, что вы сможете делать любые сценарии – важно так же и то, насколько хорошо поддерживается тем или иным браузером объектная модель документа, поскольку, в конечном итоге, 90% сценариев именно для взаимодействия с ней используются.
К сожалению, приходится констатировать, что самые существенные различия между браузерами имеются не в интерпретации самого языка, а в той части, что касается взаимодействия с DOM. Вернее даже будет сказать, что в зависимости от того, насколько хорошо тот или иной браузер поддерживает DOM, и зависит не только удобство, но и вообще возможность написания тесно взаимодействующих с документом сценариев JavaScript. Именно по этой причине разделяют ядро языка (то, что было рассмотрено в табл. 4.1), и его возможности по работе с документом, а именно – поддержка событий, взаимодействие с элементами XHTML, с окнами браузера, фреймами и т.д.
По ходу дальнейшего ознакомления с DOM и JavaScript мы не раз еще рассмотрим особенности работы каждого браузера, а пока постараемся свести воедино всю информацию, касающуюся поддержки различных уровней DOM рассматриваемыми программами просмотра. Но прежде надо отметить, что DOM так же разделяется на несколько категорий – на ядро и HTML для уровня 1, на ядро, стиль и события для уровня 2 и т.д. Кроме того, недавно была принята спецификация DOM уровня 3, которая также подразумевает логическое разделение объектной модели на несколько различных составляющих. Если попробовать объединить все имеющиеся стандарты DOM и браузеры, то можно получить примерно такую картину:
- все современные браузеры практически полностью поддерживают DOM уровня 1, как ядро, так и HTML;
- ядро DOM уровня 2 было заложено уже в процессе разработки браузера Mozilla, и на сегодня отлично поддерживается Gecko-браузерами.
- при переходе от Opera 6 к Opera 7 разработчиками программы была проделана значительная работа по поддержке DOM 2, в результате чего Opera начиная с версии 7 в целом можно считать совместимым с DOM уровня 2 браузером.
- в MSIE 6 так же имеется черты, свойственные DOM уровня 2, однако полной поддержки нет и в 8-й версии;
- DOM уровня 3 так и не получил реальной поддержки от производителей браузеров.
Учитывая все вышеизложенное, приводимые в книге примеры будут опираться на возможности JavaScript 1.3/1.5 и DOM уровня 2, с учетом особенностей и расширений реальных браузеров. Вместе с тем, мы рассмотрим так же и некоторые нововведения, появившиеся в DOM 3.
2011-07-24