Оживляем веб-страничку

Олег НИКИТЕНКО,
[email protected]

Несколько простых примеров составления сценариев на JavaScript

После прохождения "курса молодого бойца" по оформлению веб-страничек ("К+П" N4-11/2001) у многих читателей, вероятно, появилось желание сделать их более оригинальными. Например, запустить "бегущую строку", запрограммировать реакцию на определенные действия пользователя или просто автоматизировать обновление страницы, чтобы на ней всегда стояло сегодняшнее число или чтобы браузер сам определял дату последнего обновления. А может быть, пускай страница сама дает рекомендации, каким браузером ее лучше просматривать?..

Почему бы и нет? Для этого нужно воспользоваться специальным языком программирования, который будет понятен браузеру. Именно такие возможности и предоставляет "язык сценариев" JavaScript (не путать с Java! Несмотря на созвучие, это разные языки).

Разработчиком JavaScript считается компания Netscape. Сейчас доступны несколько версий этого языка. Обычно каждый новый релиз браузера поддерживает и более свежую версию JavaScript.

Соответствие между версиями
JavaScript и Netscape Navigator

JavaScript Navigator
1.0 2.0
1.1 3.0
1.2 4.0-4.05
1.3 4.06-4.7x
1.4-1.5 6.0 Mozilla

По имеющимся данным, оба последних релиза (5.x и 6.0) браузера Opera поддерживают JavaScript не выше версии 1.3. Аналогичная ситуация сложилась и с Internet Explorer 5.

Прежде всего хотелось бы отметить, что некоторые функции, несмотря на одинаковые названия, работают в разных браузерах по-разному. Поэтому веб-странички, отлаженные, например, в Internet Explorer, в Navigator или Opera могут выглядеть совсем не так, как того вы хотели, или вообще никак не выглядеть. Некоторые различия наблюдаются даже для разных релизов одного и того же браузера.

Для упрощения поставленной задачи мы будем ориентироваться на два браузера: Internet Explorer 5 (стандартная "начинка" подавляющего большинства ПК под управлением Windows 98) и Opera 5 (которому я отдаю предпочтение ввиду скорости работы и суперкомпактности).

Одним из преимуществ JavaScript является то, что код выполняется всегда, независимо от того, поддерживает браузер язык Java или нет. Поддержка JavaScript реализована во многих современных браузерах: Internet Explorer, Netscape Navigator, Opera…

К сожалению, JavaScript (как, впрочем, и Java) не лишен недостатков. К основным из них я бы отнес два. Первый заключается в том, что эти "умные" программы способны выполнять на ПК пользователя разные действия. Так, случайно попав на сайт какого-нибудь недоброжелателя, можно лишиться паролей доступа к сети или номеров электронных кредиток. Конечно, можно отключить в браузере выполнение сценариев, но тогда что за удовольствие путешествовать по "неживому" сайту?

Второй недостаток - невозможность защитить код веб-страницы. Любой желающий может просмотреть ее HTML-код (вместе с JavaScript), скопировать интересующие его фрагменты и использовать их в личных целях.

Как же работают странички с JavaScript?

Структура веб-страницы с JavaScript практически не отличается от страницы без сценариев. Нужно только вставить в определенную область HTML-документа необходимый код. В общем случае структура HTML-страницы может иметь такой вид.

<HTML>
<HEAD>
<TITLE> Заголовок </TITLE>
<SCRIPT language="JavaScript">
function FFF1() {
<!-тело функции 1 -->
}
<!-- ..... -->
function FFFn() {
<!-- тело функции n -->
}
</SCRIPT>
</HEAD>
<BODY>
<!-- тело веб-страницы: обращение к функциям FFF1(),...FFFn() -->
</BODY>
</HTML>

Рассмотрим простейший вариант. Браузер загружает страницу, которая выдает какое-нибудь сообщение (рис. 1). Для этого можно использовать следующий код:

<HTML>
<HEAD>
<TITLE> Приветствие </TITLE>
<BODY>
<!-- Ваш комментарий... -->
<SCRIPT language="JavaScript">
alert('С Днем рождения!')
</SCRIPT>
</HEAD>
</BODY>
</HTML>

В данном случае использована стандартная функция alert. В качестве аргумента ей передается строковая переменная, содержимое которой отображается в отдельном окне. Кстати, в данном случае кавычки в строке <SCRIPT language="JavaScript"> можно опустить и вообще сократить код до минимума, оставив лишь <SCRIPT>.

Строка <SCRIPT language="JavaScript"> выполняет несколько функций. Во-первых, она информирует браузер, что фрагмент кода написан на языке JavaScript, а не на VBScript. Последний поддерживается далеко не всеми браузерами (за все время серфинга я встречал его только на сайте MP3.com). Во-вторых, браузеру сообщается, что здесь расположен фрагмент встроенного сценария на JavaScript, который нужно выполнить. "Сообразительные" браузеры последних версий различают и версию языка. О том, как это сделать, мы поговорим позже.

Комментарии внутри скриптов не отличаются от обычного HTML. Началом служит комбинация символов <!--, концом - -->. Однако можно использовать и стиль комментариев, принятый в C++ - две косые (//).

Особо хотелось бы отметить следующее. Первое и, пожалуй, самое главное - не злоупотребляйте комментариями. Это увеличивает размер веб-страничек, что пользователи не всегда любят. Поэтому известный принцип великого марксиста "лучше меньше, да лучше" здесь как нельзя кстати. Во-вторых, комментарии помогают... скрывать сценарии от браузеров, которые их не поддерживают. Обычно в таком случае речь идет об устаревших версиях или нестандартном софте. Для этого в первой строке сценария ставится "начало" комментария, а в конце - его окончание. В нашем примере фрагмент функции можно было бы записать так:

<SCRIPT language="JavaScript">
<!--
alert('С Днем рождения!')
//-->
</SCRIPT>

Данная "добавка" никоим образом не влияет на выполнение сценария. Однако для упрощения все последующие фрагменты кода будут без этих символов. А теперь вернемся к самой программе. В ходе загрузки нашего HTML-файла откроется дополнительное окно с приветствием "С Днем рождения" и единственной кнопкой OK. Однако если на страничке используется несколько различных функций, обращающихся то к одной, то к другой подпрограмме, то будет корректнее (с точки зрения программирования и для наглядности) использовать именно подпрограммы-функции. В таком случае данный фрагмент кода будет выглядеть немного иначе.

<HTML>
<HEAD>
<TITLE> Приветствие </TITLE>
<SCRIPT language="JavaScript">
function hellotoyou() {
alert('С Днем рождения!');
 return true
}
</SCRIPT>
</HEAD>
<BODY>
<SCRIPT language="JavaScript">
 <!-- вызов функции приветствия -->
 hellotoyou()
</SCRIPT>
</BODY>
</HTML>

Функция обычно возвращает в вызывающую программу какое-то значение. Поэтому ее последней строкой является оператор return. Впрочем, при отсутствии необходимости его можно пропустить.

Конечно, вызвать функцию из основного тела программы можно и с помощью гиперссылки (хотя такой вариант я бы не рекомендовал):

<BODY>
<P>Для отображения приветствия щелкни
 <A href="javascript:hellotoyou()"> здесь!</A>
</BODY>

Но после окончания работы функции некоторые браузеры (например, Internet Explorer) будут "ругаться", пытаясь загрузить из сети какой-то файл. А вот в Opera и Navigator 6 этого не произойдет (рис. 2).

Этот фрагмент кода можно сделать более корректным с точки зрения IE и Opera, немного изменив содержимое строки в основном теле программы, например, так:

<P>После нажатия появится еще одно окно... щелкни
<A href="javascript:void(0);" onClick="hellotoyou();"> здесь!</A>

Теперь программа корректно функционирует и в Internet Explorer 5, и в Opera 5, и в Navigator 6. В более ранних версиях Opera (3.21-3.62) код также работоспособен, но там появляется "лишнее" окно с сообщением javascript execution failed. Впрочем, я думаю, что таким "дефектом" можно пренебречь. А если хотите от него избавиться - просто установите более новый релиз.

Вернемся к оператору return. Сделаем так, чтобы сообщение выводилось в текущем окне. Тогда код примера примет вид:

<HEAD>
<!-- ..... -->
<SCRIPT language="JavaScript">
function hellotoyou() {
 return ('С Днем рождения!');
}
</SCRIPT>
</HEAD>
<BODY>
<SCRIPT>
 document.write (hellotoyou());
</SCRIPT>
</BODY>

Вызов функции осуществляется при помощи оператора вывода на экран document.write(). Сама же функция состоит всего из одного оператора, возвращающего значение строковой переменной. Приветствие в данном случае появится не в отдельном окне, а прямо в основном окне браузера.

Попытаемся изменить код таким образом, чтобы сообщение выводилось не в теле основной программы, а в вызываемой функции. Как это сделать? Очень просто:

<SCRIPT language="JavaScript">
function hellotoyou() {
 document.write('С Днем рождения!');
 return true;
}
</SCRIPT>
</HEAD>
<BODY>
<SCRIPT>
 hellotoyou();
</SCRIPT>
</BODY>

Стандартный черный текст на белом фоне не очень-то привлекателен. Добавим цвета. Цвета и размер шрифтов, цвет фона и ссылок, а также другие атрибуты достаточно "прописать" в том же операторе document.write(). Например, сделаем черный текст на фоне aquamarine, а отдельные слова приветствия выделим синим (рис. 3). Код будет выглядеть так:

<SCRIPT language="JavaScript">
function hellotoyou() {
 document.write('<BODY text="#000000" link="#4040C0"
  vlink="#0080FF" alink="#FF0000" bgcolor="#7FFFD4">');
 document.write("<FONT face=Arial size=3>");
 document.write('С Днем');
 document.write("<FONT color=blue><U><B> рождения,</B></U></FONT>, программер!");
 document.write("</FONT></BODY>");
 return true;
}
</SCRIPT>

Для того чтобы иметь возможность использовать в тексте, выводимом через функцию document.write(), кавычки, можно поступить так. Общее "обрамление" сделать с помощью двойных кавычек, а апострофы и т.п. внутри текста - одинарными или наоборот. Хотя можно использовать и зарезервированные условные обозначения некоторых символов. Так, двойным кавычкам соответствует комбинация (так называемое внутреннее представление ESC-кода) \u0022, одинарным - \u0027, обратной косой черте - \u005c. К сожалению, при просмотре страничек в Opera такой вариант "не проходит". Чтобы удовлетворить одновременно оба браузера, можно использовать следующие ESC-последовательности: соответственно \", \' и \\. Для двойных кавычек во всех трех браузерах можно использовать символ &quot;. Эти рекомендации справедливы и для Navigator 6.2.

Особо хотелось бы обратить внимание на составление скриптов. На ошибку в HTML-коде иногда укажет сам браузер. Если же ошибиться даже одной буквой в коде скрипта - например, написать <SCRIPT language="JavaSсrit"> вместо JavaSсript, браузер преспокойно это "проглотит". В лучшем случае код не будет выполняться. В худшем может "зависнуть" компьютер. Хорошо, если собственный. А если вы уже успели разместить его на веб-страничке в интернете?..

Раз окно, два окно…

Теперь попробуем сделать собственное окно с приветствием. Размер и содержимое придумаем сами. Передвинем сообщение немного вниз - на 50 пикселей (topMargin=50) - и "отцентруем". Для этого напишем следующий код:

<BODY text="#000000" bgcolor="#7FFFD4"
topmargin=50 marginwidth=10 marginheight=0>
<A name="_top"></A>
<CENTER>
<SCRIPT language="JavaScript">
<!--
function OpenWin() {
 myWin1=window.open("", "top_", "width=500, height=400,
 status=no, toolbar=no, resizable=yes, scrollbars=yes,
 menubar=yes");
  document.ss.submit();
}
// -->
</SCRIPT>
<BR>
<FORM name="ss" method=post action="programr.htm" target="top_">
<INPUT type="hidden" name="doc_number" value="" ></input>
</FORM>
<PRE class="left">
<FONT size=3>
С Днем рождения,
<A href="javascript:OpenWin()"><U><B>программер!</B></U></A>
</FONT>
</PRE>
</BODY>

При загрузке странички появится уже знакомое нам приветствие. Выделение слова "программер" намекает посетителю на то, что, если по нему щелкнуть, откроется второе окно. Например, с пояснением для новичков, что оно означает… О назначении функции OpenWin(), надеюсь, вы и сами догадались. Правильно, она использует стандартную функцию window.open() для создания и открытия окна шириной 500 и высотой 400 пикселей. Для удобства и "сжатия" этого окна мы отключили отображение нижней строки состояния, где обычно выводятся сообщения о загрузке страницы, а также окно с навигационными кнопками. Подробнее о параметрах страницы речь пойдет позже.

Если щелкнуть на слове "программер", откроется файл programr.htm. Его HTML-код может быть, например, таким:

<HTML>
<HEAD>
<TITLE> Словарик </TITLE>
</HEAD>
<BODY text="#000000" bgcolor="#FFFFFF">
<P> <U><B>Программер</B></U> (жарг.) - программист.
</BODY>
</HTML>

Правда, здесь есть один недостаток. Для того чтобы закрыть "словарь", необходимо зайти в меню и выбрать команду Файл->Закрыть. Согласитесь, это довольно неудобно. Можно ли автоматизировать этот процесс? Конечно. Для этого нужно создать, например, радиокнопку, которая будет вызывать соответствующую функцию (которая называется window.close()):

<BODY text="#000000" bgcolor="#FFFFFF">
<P> <U><B>Программер</B></U> (жарг.) - программист.
<CENTER><FORM>
<INPUT type="button" value="Закрыть" onClick="window.close()">
</FORM></CENTER>
<NOSCRIPT>
<I>Используйте кнопку "Возврат"/"BACK" вашего браузера
для возврата на предыдущую страницу.</I>
</NOSCRIPT><BR clear="all">
</BODY>

Вместо функции window.close() можно использовать self.close(). Обе они отлично справляются со своими обязанностями и в Internet Explorer, и в Opera. Кстати, для Opera можно написать просто close().

Конечно, для удобства нашу программу желательно дополнить еще небольшим фрагментом, с помощью которого можно было бы спросить юзера, желает ли он закрыть окно или нет? Для этого достаточно внести в код такие косметические изменения:

<HTML>
<HEAD>
<TITLE> Словарик с кнопкой закрытия окна.
 Вариант с запросом. </TITLE>
<SCRIPT language="JavaScript">
<!--
 function OnExit() {
  if (confirm ("Вы действительно хотите
   закрыть это окошко?"))
    top.close();
 }
//-->
</SCRIPT>
</HEAD>
<BODY text="#000000" bgcolor="#FFFFFF">
<P> <U><B>Программер</B></U> (жарг.) - программист.
<CENTER><FORM>
<INPUT type="button" value="Закрыть" onClick="OnExit()">
</FORM></CENTER>
<NOSCRIPT>
<I>Используйте кнопку "Возврат"/"BACK" вашего браузера
для возврата на предыдущую страницу.</I>
</NOSCRIPT><BR clear="all">
</HEAD>
</BODY>
</HTML>

Для обработки запроса здесь используется стандартная функция confirm(). За вызов функции-обработчика запроса OnExit() отвечает оператор onClick.

А можно ли организовать навигацию по веб-страницам - например, возврат на предыдущую страницу - без использования стандартных кнопок браузера? Конечно. Для этого достаточно "повесить" на каждую страничку соответствующую кнопку перехода:

<CENTER><FORM>
<INPUT type="button" value="Возврат" onClick="history.go(-1)">
</FORM></CENTER>
<NOSCRIPT>
<I>Используйте кнопку "Возврат"/"BACK" вашего браузера
для возврата на предыдущую страницу.</I>
</NOSCRIPT><BR clear="all">

Вместо оператора history.go(-1) можно использовать history.back(1). Результат будет одинаковым и в IE, и в Opera.

Теперь, похоже, все в порядке. Кстати, что означает текст между тегами <NOSCRIPT> и </NOSCRIPT>? Дело в том, что некоторые браузеры не поддерживают JavaScript и, следовательно, могут не отобразить нашу кнопку. И это относится не к какой-то экзотике, а к обычным браузерам. Например, если отключить выполнение JavaScript, указанная строка не будет видна в старой версии 3.x и в новой 5.x Internet Explorer. В таком случае нужно дать пользователю "руководство к действию".

При создании окна используются несколько параметров. Давайте разберемся, для чего они предназначены. Для активации параметра достаточно присвоить ему значение. Описания некоторых параметров, использованных в нашем примере, представлены в следующей таблице.

Параметр Значение Описание
width 500 ширина окна в пикселях
height 400 высота окна в пикселях
status no не показывать строку состояния, в которой отображаются сообщения о загрузке страницы
toolbar no отключить панель навигационных кнопок. Этот режим работает в IE5 и Navigator 6.2, но не в Opera, так как в этом браузере открывается новое окно, а не копия старого (как в IE)
menubar 0 не отображать строку меню. Как и предыдущий параметр, работает в IE и Navigator (так как открывается еще одна копия браузера), однако в Opera (3 и 5) эффекта не дает
scrollbars yes отображать полосы прокрутки
resizable yes разрешение изменять размер окна. В Opera эффекта не дает
location yes показывать URL, по которому обращается браузер (в т.ч. локальные имена файлов). Имеет смысл использовать в IE и Opera версии не ниже 5, но не в Opera 3 (там адресная строка всегда доступна)
directories yes отображать в строке адреса меню ссылок (только для Internet Explorer и Navigator)

Теперь немного изменим текст программы, демонстрирующей открытие окна. Пусть текст приветствия будет доступен только при загрузке страницы с отключенной графикой. Если же графика включена, на месте приветствия будет небольшая картинка (назовем ее abc.gif), по которой нужно будет щелкнуть для просмотра "словарика".

<HTML>
<HEAD>
<TITLE> Приветствие </TITLE>
<SCRIPT language="JavaScript">
<!--
function mw_open() {
 var frame1 = window.open ("program2.htm", "frame1",
  "copyhistory=0, directories=0, height=500, location=0,
  menubar=0, scrollbars=yes, status=0, toolbar=0,
  width=400");
 frame1.focus();
}
//-->
</SCRIPT>
</HEAD>
<BODY bgcolor="#FFFFF0" marginwidth=0 marginheight=0 topmargin=0
leftmargin=0 text="#000000" link="#000000">
<A href="#" onClick="mw_open()";>
<NOSCRIPT>
<A href="program2.htm" target="_new">
</NOSCRIPT>
<IMG src="image/abc.gif" width=80 height=50 border=0
vspace=0 hsapce=0 alt="С Днем рождения, программер!">
</A>
<BR> <BR>
</SCRIPT>
</BODY>
</HTML>

Рассмотренные примеры с окнами, конечно, удобны. Но есть и более простой вариант. Выполнение сценария можно связать с определенным событием. Например, с попаданием курсора мыши на какую-то ссылку, чтобы в ответ на это событие браузер показал не URL, а комментарий к ссылке. Как это сделать? Добавить к тегу <A> два атрибута: onMouseOver и onMouseOut:

<HTML>
<HEAD>
<TITLE> Подсказка для "несмышленой" мышки </TITLE>
<BODY>
<P>С днем рождения,
<A anchor definition
 onMouseOver="self.status='поздравления с Yahoo';
 return true;"
 onMouseOut="self.status='';
 return true;"
 href="http://www.yahoo.com">
<U>программер!</U></A>
<P>Еще раз с днем рождения,
<A anchor definition
 onMouseOver="self.status='поздравления с AltaVista'
 return true;"
 onMouseOut="self.status='';
 return true;"
 href="http://www.altavista.com">
<U>программер!</U></A>
<P>И еще раз с днем рождения,
<A anchor definition
 onMouseOver="self.status='поздравления с Рамблера';
 return true;"
 onMouseOut="self.status='';
 return true;" href="http://www.rambler.ru">
<U>программер!</U></A>
</HEAD>
</BODY>
</HTML>

В self.status записывается текст. Параметр onMouseOver работает, когда курсор мыши попадает на URL, а onMouseOut очищает строку после того, как курсор покидает ссылку. Подводим курсор к слову "программер" и… Вместо URL браузер сообщает о новых поздравлениях от Yahoo, Altavist'ы и Рамблера!

Существует целый набор событий, которые можно связать со сценариями. Кроме упоминавшихся onClick, onMouseOver и onMouseOut, есть также onLoad, onChange, onUnload, onBlur, onReset, onFocus, onSubmit и др. Попробуйте поэкспериментировать с ними самостоятельно. Мы же перейдем к работе с параметрами в JavaScript.

(окончание в следующем выпуске)