Сценарии JavaScript в активных страницах Web

         

События, связанные с объектами


Сделаем еще одно очень важное замечание относительно объектов браузера.

С каждым таким объектом связывается определенный набор событий, обработка которых возможна в сценарии JavaScript.

Например, с объектом window связаны события onLoad и onUnload. Первое из этих событий возникает, когда браузер завершает загрузку окна и всех расположенных в нем фреймов (если эти фреймы определены в окне). Второе событие возникает, когда пользователь завершает работу с документом, закрывая окно браузера или переключаясь на другой документ.

Сценарий JavaScript может, например, при обработке события onLoad выводить для пользователя приветственное сообщение или запрашивать дополнительную информацию. При завершении работы с окном (когда возникает событие onUnload) сценарий может освобождать какие-либо ресурсы, связанные с этим окном, или  выводить сообщение на экран монитора.

С другими объектами браузера также связаны события. Мы расскажем о них при описании этих объектов.



Создание анимационных изображений


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

На рис. 5.2 мы показали документ HTML, в котором используется такая анимация.

Рис. 5.2. Анимация с помощью сценария JavaScript

В окне браузера последовательно отображаются кадры анимационного изображения (рис. 5.3), причем сначала в прямой, а затем - в обратной последовательности. Это выглядит так, как будто слово Noise периодически тонет в цветном шуме и затем проявляется вновь. Заметим, что похожий эффект мы уже получали совершенно другими средствами в аплете Java, исходный текст которого был опубликован в журнале “Мир ПК” №1 за 1998 год.



Рис. 5.3. Изображения отдельных кадров анимационной последовательности

Также мы обратим ваше внимание, что для достижения подобного эффекта при помощи многосекционного файла GIF размер этого файла было бы необходимо удвоить. Причина этого заключается в том, что вам пришлось бы включить в файл кадры вначале в прямой, а затем в обратной последовательности. Сценарий JavaScript позволяет более тонко управлять процессом отображения кадров, что можно использовать для достижения достаточно сложных визуальных эффектов относительно простыми средствами.

Исходный текст документа HTML, в котором имеется сценарий, выполняющий анимацию, показан в листинге 5.2.

Листинг 5.2. Файл chapter5/noise/noise.html

<HTML>

  <HEAD>

    <TITLE>Animation with JavaScript</TITLE>

    <SCRIPT LANGUAGE="JavaScript">

    <!--

    var i=1;

    var bForward=true;

    function showNextImage()

    {

      if(bForward)

      {

        i++;

        if(i>17)

        {

          bForward=false;

        }

      }

      else

      {

        i--;

        if(i<2)

        {

          bForward=true;

        }

      }

      document.Img.src= "img0" + i + ".gif";


      setTimeout("showNextImage()", 100);

    }

    // -->

    </SCRIPT>

  </HEAD>

  <BODY BGCOLOR=white>

    <IMG SRC="img01.gif" NAME="Img">

    <SCRIPT LANGUAGE="JavaScript">

    <!--

      showNextImage();

    // -->

    </SCRIPT>

  </BODY>

</HTML>

В теле документа с помощью оператора <IMG> мы разместили первый кадр анимационной последовательности:

<IMG SRC="img01.gif" NAME="Img">

С помощью параметра NAME мы задали имя Img. Это имя будет использовано сценарием JavaScript для ссылки на объект.

Кроме того, в теле нашего документа находится вызов функции showNextImage. Данная функция предназначена для отображения очередного кадра анимационной последовательности.

В области заголовка документа HTML находится определение функции showNextImage и двух глобальных переменных:

var i=1;

var bForward=true;

Переменная i хранит номер текущего кадра, отображаемого в окне браузера. Этот номер вначале увеличивается функцией showNextImage от 1 до 16, а затем снова уменьшается до 1. Изменение номера происходит на 1 (в ту или в другую сторону) при каждом вызове функции showNextImage.

В переменной bForward хранится направление изменения номера кадра. Значение true соответствует прямому направлению, а значение false - обратному.

Когда функция showNextImage получает управление, она анализирует содержимое переменной bForward. Если в этой переменной находится значение true, функция showNextImage увеличивает значение переменной i, а затем сравнивает результат с числом 17. Когда отображение всех кадров в прямой последовательности завершено, в переменную bForward записывается false, после чего при следующем вызове функции showNextImage номер текущего кадра будет не увеличиваться, а уменьшаться.

Для отображения очередного кадра функция showNextImage изменяет значение свойства src изображения document.Img, как это показано ниже:

document.Img.src= "img0" + i + ".gif";

Имя файла, в котором хранится изображение кадра, конструируется из строки “img0”, номера кадра, и строки “.gif”.

Последнее, что делает функция showNextImage перед тем как возвратить управление, - вызывает функцию setTimeout:

setTimeout("showNextImage()", 100);

Напомним, что функция setTimeout устанавливает таймер. Задержка срабатывания таймера определяется вторым параметром и в нашем случае равна 100 миллисекундам.

Когда таймер сработает, будет запущена на выполнение строка сценария JavaScript, которая была передана функции setTimeout в качестве первого параметра. Мы вызываем после окончания задержки функцию showNextImage, и таким образом обеспечиваем вызов этой функции в бесконечном цикле.


Создание cookie


Существуют два способа создание cookie, первый из которых используется расширениями сервера Web, а второй - сценариями JavaScript. Мы рассмотрим оба этих способа.



Список select


С помощью оператора <SELECT> вы можете разместить внутри формы список, допускающий выбор одной или просмотр нескольких строк. Формат оператора <SELECT> мы привели ниже:

<SELECT NAME="Имя_списка_select"

   SIZE="Размер_списка"

   MULTIPLE

   onBlur="Обработчик_события"

   onChange="Обработчик_события"

   onFocus="Обработчик_события">

   <OPTION VALUE="Значение" SELECTED> Текст

   ...

   <OPTION> Текст

</SELECT>

Все параметры оператора <SELECT> необязательные, однако для того чтобы сценарий JavaScript мог работать со списком, необходимо указать по крайней мере параметр NAME, определяющий имя списка.

Параметр SIZE задает размер видимой части списка в строках.

Если указан необязательный параметр MULTIPLE, объект select является списком просмотра, а не списком выбора.

Список может быть создан пустым и впоследствии заполнен сценарием JavaScript, или уже содержащим один или несколько элементов. Для определения элементов списка предназначен оператор <OPTION>.

Оператор <OPTION>  может иметь два параметра - VALUE и SELECTED.

Параметр VALUE определяет значение, которое передается расширению сервера Web. С помощью параметра SELECTED отмечается строка списка, выделенная по умолчанию при начальном отображении формы.

После оператора <OPTION> следует текст, отображаемый в строках списка.



Sqrt


Вычисление квадратного корня от аргумента.

Пример использования:

var nValueSqrt;

nValueSqrt = Math.sqrt(nArg);


Свойство SQRT2 - это значение квадратного корня из 2.

Пример использования:

var nValue;

nValue = Math.SQRT2;


Ссылки и метки в документе


Как мы уже рассказывали в 29 томе “Библиотеки системного программиста” с названием “Сервер Web своими руками”, для того чтобы вставить в документ HTML ссылку или локальную метку, необходимо использовать оператор <A>. В общем виде этот оператор представлен ниже:

<A HREF=Адрес URL или локальная метка

   NAME="Имя локальной метки"

   TARGET="Имя окна"

   onClick="Обработчик события: щелчок по ссылке"

   onMouseOver="Обработчик события: курсор над ссылкой">

   Текст ссылки

</A>

Описание параметров оператора <A> мы привели ниже:

Параметр

Описание

HREF

Параметр HREF задает адрес URL или имя локальной метки документа, куда будет сделан переход по ссылке

NAME

Если указан параметр NAME, оператор <A> определяет локальную метку. Значение этого параметра задает имя метки

TARGET

Параметр TARGET задает имя окна, куда будет загружен документ при выполнении ссылки. Это может быть имя существующего окна фрейма, определенного с помощью оператора <FRAMESET>, или одним из следующих зарезервированных имен - _top, _parent, _self, или _blank

onClick

С помощью параметра onClick можно определить обработчик события, который получит управление, когда пользователь сделает щелчок левой клавишей мыши по ссылке

onMouseOver

Аналогично предыдущему, однако обработчик события получит управление, когда пользователь разместит курсор мыши над ссылкой

Для каждой ссылки, размещенной в документе HTML, создается отдельный объект. Все такие объекты находятся в объекте документа Document как элементы массива links.

Сценарий JavaScript может определить свойства каждой ссылки, расположенной в документе HTML, анализируя элементы объекта links. Вот список этих свойств:

Свойство

Описание

hash

Имя локальной ссылки, если она определена в адресе URL

host

Имя узла и порт, указанные в адресе URL

hostname

Имя узла и доменное имя узла сети. Если доменное имя недоступно, вместо него указывается адрес IP

href

Полный адрес URL

pathname

Путь к объекту, указанный в адресе URL

port

Номер порта, используемого для передачи данных с сервером, указанным в данной ссылке

protocol

Строка названия протокола передачи данных (включающая символ “двоеточие”), указанного в ссылке

search

Строка запроса, указанная в адресе URL после символа “?”

target

Значение параметра TARGET, заданное в ссылке

length

Количество элементов в массиве links, то есть количество ссылок в текущем документе HTML

<
Рассмотрим пример сценария JavaScript, работающего со ссылками как с элементами массива links.

Мы приведем пример документа, с формой, списком и кнопкой Jump. Сценарий JavaScript заполняет список ссылками, размещенными в документе HTML. Внешний вид этого документа показан на рис. 2.19.



Рис. 2.19. Документ со списком расположенных в нем ссылок

Выбрав из списка ссылку и нажав кнопку Jump, вы загрузите в окно браузера документ, указанный в этой ссылке или запустите почтовую программу для подготовки и отправки сообщения (если выбрана ссылка на адрес электронной почты).

Так как список ссылок формируется сценарием динамически, новые ссылки, добавленные в документ HTML, появятся в списке автоматически без дополнительных усилий по редактированию сценария.

В нижней части этого же документа HTML, показанного на рис. 2.20, сценарий отображает детальную информацию по каждой ссылке, извлеченную из свойств объектов класса links, соответствующих ссылкам.



Рис. 2.20. Детальная информация о ссылках

Что за информация здесь отображается?

Вначале выводятся свойства перовй ссылки, содержащей адрес главной страницы нашего сервера Web в сети Internet:

 

http://www.glasnet.ru/~frolov/index.html

host: www.glasnet.ru:80

hostname: www.glasnet.ru

href: http://www.glasnet.ru/~frolov/index.html

pathname: ~frolov/index.html

port: 80

protocol: http:

search:

target:

Так как в этой ссылке указан полный адрес URL, включающий путь к файлу документа index.html, то этот путь записывается в свойство с именем pathname.

Хотя порт, с использованием которого устанавливается соединение с сервером Web, не указан, в свойства host и port записывается значение, применяемое для этой цели по умолчанию, а именно 80.

Рассмотрим следующую ссылку:

http://www.auramedia.ru/

host: www.auramedia.ru:80

hostname: www.auramedia.ru

href: http://www.auramedia.ru/

pathname:

port: 80

protocol: http:

search:

target:

Здесь путь к файлу документа HTML не указан, поэтому свойство pathname содержит пустую строку.



В ссылке на сервер Microsoft мы указали путь к каталогу java:

http://www.microsoft.com/java/

host: www.microsoft.com:80

hostname: www.microsoft.com

href: http://www.microsoft.com/java/

pathname: java/

port: 80

protocol: http:

search:

target: newwnd

Этот частичный путь оказался записанным в свойство pathname. Кроме того, для отображения содержимого сервера Microsoft должно быть создано новое окно. Имя этого окна задано как newwnd в параметре TARGET оператора <A>. С помощью этого оператора мы разместили ссылку в документе HTML. Как и следовало ожидать, имя окна оказалось записано в свойство target.

Последняя ссылка - это адрес электронной почты:

mailto:frolov@glas.apc.org

host: glas.apc.org

hostname: glas.apc.org

href: mailto:frolov@glas.apc.org

pathname:

port: 0

protocol: mailto:

search:

target:

В свойстве protocol данной ссылки записана строка “mailto:”.

Рассмотрим теперь исходный текст документа HTML, содержащий сценарий JavaScript, работающий со ссылками (листинг 2.9).

Листинг 2.9. Файл chapter2/LinksList/LinksList.html

<HTML>

  <HEAD>

    <TITLE>Links and Anchors</TITLE>

    <SCRIPT LANGUAGE="JavaScript">

    <!--

    function urlJump()

    {

      var szNewURL="";

      szNewURL =

         document.links[Sel.ListOfLinks.selectedIndex];

      window.location.href=szNewURL;

    }

    // -->

    </SCRIPT>

  </HEAD>

  <BODY BGCOLOR=white>

    <H1>Просмотр ссылок</H1>

    <FORM NAME="Sel">

      <SELECT NAME="ListOfLinks">

      </SELECT>

      <INPUT TYPE="button" VALUE="Jump!" onClick="urlJump();">

    </FORM>

    <P>Посетите эти серверы:

    <P><A HREF="http://www.glasnet.ru/~frolov/index.html">Наша домашняя страница</A>

    <BR><A HREF="http://www.auramedia.ru">Каталог программ Auramedia</A>



    <BR><A HREF="http://www.microsoft.com/java/" TARGET="newwnd">Страница сервера Microsoft про Java</A>

    <P>Пишите нам по адресу: <A HREF="mailto:frolov@glas.apc.org">frolov@glas.apc.org</A>

    <HR>

    <H1>Список ссылок</H1>

    <P> Этот список сформирован динамически сценарием JavaScript</P>

    <SCRIPT LANGUAGE="JavaScript">

    <!--

    elem = new Array();

    for(i=0; i<document.links.length; i++)

    {

      elem[i] = new Option("Elem" + i, i, false, false);

      Sel.ListOfLinks.options[i] = elem[i];

      Sel.ListOfLinks.options[i].text = document.links[i];

      document.write("<HR>");

      var szText=document.links[i] + "<BR>";

      document.write(szText.bold());

      document.write("host: ".italics() + document.links[i].host + "<BR>");

      document.write("hostname: ".italics() + document.links[i].hostname + "<BR>");

      document.write("href: ".italics() + document.links[i].href + "<BR>");

      document.write("pathname: ".italics() + document.links[i].pathname + "<BR>");

      document.write("port: ".italics() + document.links[i].port + "<BR>");

      document.write("protocol: ".italics() + document.links[i].protocol + "<BR>");

      document.write("search: ".italics() + document.links[i].search + "<BR>");

      document.write("target: ".italics() + document.links[i].target + "<BR>");

    }

    Sel.ListOfLinks.selectedIndex=0;

    // -->

    </SCRIPT>

  </BODY>

</HTML>

В секции заголовка документа HTML определена функция urlJump, загружающая в окно браузера объект, соответствующий выбранной в списке ссылке:



function urlJump()

{

  var szNewURL="";

  szNewURL =

     document.links[Sel.ListOfLinks.selectedIndex];

  window.location.href=szNewURL;

}

Список ссылок, а также кнопка Jump, служащая для активизации выбранной ссылки, определена следующим образом:

<FORM NAME="Sel">

  <SELECT NAME="ListOfLinks">

  </SELECT>

  <INPUT TYPE="button" VALUE="Jump!" onClick="urlJump();">

</FORM>

Имя формы, необходимое сценарию JavaScript для доступа к списку и кнопке, определено в параметре NAME оператора <FORM> как Sel.

Список с именем ListOfLinks создается оператором <SELECT>. Первоначально в списке нет ни одного элемента. Все элементы будут добавлены в список сценарием JavaScript.

Кнопка Jump активизирует фукнцию urlJump, для чего в ее определении указан обработчик события onClick.

Обратите внимание на то, как функция urlJump адресуется к выбранному элементу списка:

szNewURL = document.links[Sel.ListOfLinks.selectedIndex];

Здесь мы взяли форму Sel и указали имя списка ListOfLinks как имя одного из свойств формы. Номер выделенного элемента списка находится в свойстве списка с именем selectedIndex.

Наш сценарий заполняет массив ссылок links и список Sel.ListOfLinks таким образом, что первый элемент массива links соответствует первой ссылке в списке, второй элемент массива - второму элементу и так далее. Поэтому выражение Sel.ListOfLinks.selectedIndex является номером ссылки в массиве links, которую необходимо активизировать. Функция urlJump записывает эту ссылку в переменную szNewURL, а затем устанавливает значение свойства window.location.href.

Рассмотрим теперь сценарий JavaScript, определенный в теле документа HTML.

Прежде всего, в этом сценарии мы создаем массив elem:

elem = new Array();

Этот массив предназначен для хранения элементов динамически формируемого списка, определенного пустым в форме Sel.

Далее в сценарии располагается цикл по всем ссылкам, размещенным в документе HTML:



for(i=0; i<document.links.length; i++)

{

  . . .

}

Количество ссылок находится в свойстве length объекта links, поэтому переменная цикла i изменяет свое значение от 0 до document.links.length.

В цикле мы создаем новый элемент списка и записываем в него текст ссылки:

elem[i] = new Option("Elem" + i, i, false, false);

Sel.ListOfLinks.options[i] = elem[i];

Sel.ListOfLinks.options[i].text = document.links[i];

Способ создания элемента списка будет подробно описан в главе, посвященной работе сценариев JavaScript с формами. Здесь мы только отметим, что текстовая строка, соответствующая ссылке, извлекается из массива links как document.links[i].

Далее после записи в документ HTML разделительной линии наш сценарий записывает в него текст ссылки, выделяя его жирным шрифтом:

document.write("<HR>");

var szText=document.links[i] + "<BR>";

document.write(szText.bold());

Вслед за этим в документ HTML записываются все свойства ссылки, извлеченные из текущего элемента массива links. Например, имя узла и номер порта извлекаются и записываются в документ HTML следующим образом:

document.write("host: ".italics() + document.links[i].host + "<BR>");

Последнее, что делает наш сценарий уже после завершения цикла, это выделение первого элемента в списке Sel.ListOfLinks:

Sel.ListOfLinks.selectedIndex=0;

Для этого номер выделяемого элемента (в нашем случае это 0) записывается в свойство списка с именем selectedIndex.


Старшинство операторов JavaScript


Ниже мы привели таблицу старшинства операторов JavaScript. С помощью этой таблицы можно определить порядок вычисления составных операторов. При этом следует учитывать, что все логические операции выполняются слева направо.

Первыми вычисляются операторы, расположенные в начале таблицы старшинства:

Оператор

Описание

. [] ()

Доступ к полю, индексирование в массиве, вызов функции

++ -- - ~ !

Унарные операторы

* / %

Умножение, деление, вычисление остатка от деления

+ - +

Сложение, вычитание, слияние текстовых строк

<< >> >>>

Битовые сдвиги

< <= > >=

Меньше, меньше или равно, больше, больше или равно

== !=

Равенство, неравенство

&

Логическая операция И

^

Логическая операция ИСКЛЮЧАЮЩЕЕ ИЛИ

|

Логическая операция ИЛИ

&&

Логический оператор отношения И

Логический оператор отношения ИЛИ

?:

Условный оператор

= += -= *= /= %= >>= >>>= <<= |= &= ^=

Присваивание

,

Многократное вычисление



Перечислим свойства класса Math. Все


Перечислим свойства класса Math. Все эти свойства являются математическими константами, поэтому сценарий JavaScript не может изменять их значение.

Свойства объекта button


Объект button имеет два свойства, отражающие значения соответствующих параметров оператора <INPUT>:

Свойство

Описание

name

Значение параметра NAME

value

Значение параметра VALUE



Свойства объекта checkbox


Объект checkbox имеет несколько свойств, отражающих значения соответствующих параметров оператора <INPUT>:

Свойство

Описание

name

Значение параметра NAME

checked

Свойство типа Boolean, отражающее состояние переключателя. Если переключатель включен, свойство имеет значение true, в противном случае - false. С помощью этого свойства сценарий может изменять состояние переключателя

value

Значение параметра VALUE

defaultChecked

Свойство типа Boolean, отражающее значение параметра CHECKED. Если параметр CHECKED присутствует в определении переключателя, свойство имеет значение true, в противном случае - false. Сценарий может определять или устанавливать значение этого свойства



Свойства объекта document


Перечислим свойства объекта document, доступные сценарию JavaScript:

Свойство

Описание

alinkColor

Содержимое параметра ALINK

anchors

Массив локальных меток, размещенных в документе. Эти метки применяются для организации ссылок внутри документа

applets

Массив объектов, соответствующих аплетам Java, расположенным в документе HTML

bgColor

Содержимое параметра BGCOLOR

cookie

Значение cookie для текущего документа. О том, что это такое, мы расскажем в последней главе нашей книги

embeds

Массив объектов plug-in, содержащихся в документе HTML

fgColor

Содержимое параметра TEXT

forms

Массив, содержащий в виде объектов все формы, расположенные в документе HTML

images

Массив растровых изображений, включенных в документ

lastModified

Дата последнего изменения документа HTML

linkColor

Содержимое параметра LINK

links

Массив, содержащий все ссылки в документе HTML

location

Полный адрес URL документа HTML

referrer

Адрес URL вызывающего документа HTML

title

Заголовок документа, заданный с помощью оператора <TITLE>

URL

Полный адрес URL документа HTML

vlinkColor

Содержимое параметра VLINK

Объект document может содержать в себе другие объекты, доступные как свойства:

Свойство

Описание

anchor

Локальная метка, определенная в документе HTML с помощью оператора <A>

form

Форма, определяемая в документе HTML с помощью оператора <FORM>

history

Список адресов URL, посещенных пользователем

link

Текст или изображение, играющее роль гипертекстовой ссылки. Создается с помощью оператора языка HTML <A>, в котором дополнительно задаются обработчики событий onClick и onMouseOver 



Свойства объекта form


Объект form имеет два набора свойств, состав одного из которых является фиксированным, а состав другого зависит от того, какие поля и органы управления определены в форме.

Первый набор свойств приведен ниже:

Свойство

Описание

action

Содержит значение параметра ACTION

elements

Массив всех элементов (полей и органов управления), определенных в форме

encoding

Содержит значение параметра ENCTYPE

length

Размер массива elements

method

Содержит значение параметра METHOD

target

Содержит значение параметра TARGET

Большинство свойств первого набора просто отражает значения соответствующих параметров оператора <FORM>. Вы можете их использовать в сценариях JavaScript для проверки параметров.

Что же касается массива elements, то в нем находятся объекты, соответствующие полям и органам управления, определенным в форме. Эти объекты образуют второй набор свойств объекта form:

Свойство

Описание

button

Кнопка с заданной надписью

checkbox

Переключатель типа Check Box. Может использоваться в составе набора независимых друг от друга переключателей или отдельно

hidden

Скрытое поле, которое не отображается. Содержимое этого поля может быть считано и проанализировано расширением сервера Web, либо сценарием JavaScript

password

Текстовое поле для ввода паролей. Набранный в этом поле текст не отображается на экране

radio

Переключатель для группы зависимых друг от друга переключателей. Используется обычно для выбора одного значения из нескольких возможных

reset

Кнопка, с помощью которой пользователь может сбросить содержимое полей ввода и состояние переключателей в их исходное состояние

select

Список произвольных текстовых строк

submit

Кнопка для посылки данных из заполненной формы расширению сервера Web. Для этой кнопки можно задать произвольную надпись

text

Однострочное текстовое поле

textarea

Многострочное текстовое поле



Свойства объекта password


Сценариям JavaScript доступны три свойства поля редактирования password:

Свойство

Описание

defaultValue

Отражает состояние параметра VALUE

name

Значение параметра NAME

value

Текущее содержимое поля редактирования

Так же, как и для поля text, сразу после отображения поля редактирования свойства defaultValue и value хранят одинаковые строки. Когда пользователь редактирует текст, все изменения отражаются в свойстве value.

Изменяя содержимое свойства value, сценарий может изменить содержимое поля редактирования типа password.



Свойства объекта radio


Объект radio имеет следующие свойства:

Свойство

Описание

name

Значение параметра NAME

checked

Свойство типа Boolean, отражающее состояние переключателя. Если переключатель включен, свойство имеет значение true, в противном случае - false. С помощью этого свойства сценарий может изменять состояние переключателя

length

Количество переключателей типа radio, определенных в группе с именем, заданным параметром NAME

value

Значение параметра VALUE

defaultChecked

Свойство типа Boolean, отражающее значение параметра CHECKED. Если параметр CHECKED присутствует в определении переключателя, свойство имеет значение true, в противном случае - false. Сценарий может определять или устанавливать значение этого свойства



Свойства объекта select


Ниже мы перечислили свойства объекта select, доступные сценарию JavaScript:

Свойство

Описание

length

Количество элементов (строк) в списке

name

Значение параметра NAME

options

Массив объектов options, соответствующих элементам массива, заданным при помощи оператора <OPTION>

selectedIndex

Номер выбранного элемента или первого элемента среди нескольких выбранных (если указан параметр MULTIPLE и пользователь выбрал в списке несколько элементов)

Одним из свойств списка select является массив options. В этом массиве хранятся элементы списка, определенные оператором <OPTION>. Каждый элемент такого массива есть ни что иное как объект со следующим набором свойств:

Свойство

Описание

defaultSelected

Отражает состояние параметра SELECTED

index

Порядковый номер (индекс) элемента списка

length

Количество элементов в выбранном объекте

name

Значение параметра NAME

selected

С помощью свойства selected сценарий JavaScript может выбрать данный элемент

selectedIndex

Номер выбранного элемента

text

Текст, указанный после оператора <OPTION>

value

Значение параметра VALUE



Свойства объекта text


Сценариям JavaScript доступны три свойства поля редактирования как объекта класса text:

Свойство

Описание

defaultValue

Отражает состояние параметра VALUE

name

Значение параметра NAME

value

Текущее содержимое поля редактирования

Сразу после отображения поля редактирования свойства defaultValue и value хранят одинаковые строки. Когда пользователь редактирует текст, все изменения отражаются в свойстве value.

Заметим, что изменяя содержимое свойства value, сценарий JavaScript может изменить содержимое поля редактирования.



Свойства объекта window


Объект window имеет свойства, описывающие размеры окна, расположенные в окне фреймы, имя окна, содержимое строки состояния окна и другие:

Свойство

Описание

defaultStatus

Сообщение, отображаемое в строке состояния окна браузера по умолчанию

frames

Массив всех фреймов данного окна

length

Количество фреймов в родительском окне

name

Имя окна, указанное при его открытии методом open, а также в параметре TARGET оператора <A> или в параметре NAME оператора <FORM> 

parent

Синоним имени окна. Относится к окну, содержащему набор фреймов

self

Синоним имени окна. Относится к текущему окну

status

Текущее сообщение, отображаемое в строке состояния окна браузера

top

Синоним имени окна. Относится к окну верхнего уровня

window

Синоним имени окна. Относится к текущему окну

Что касается свойства defaultStatus, то оно используется только в браузере Netscape Navigator. Если записать в это свойство произвольное сообщение, оно будет отображаться в строке состояния Netscape Navigator, когда окно браузера выдвигается на передний план. К сожалению, браузер Microsoft Internet Explorer версий 3.02 и 4.0 игнорирует свойство defaultStatus.

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

Заметим, однако, что в браузере Microsoft Internet Explorer версии 4.0 строка состояния разделена на несколько областей. Область, содержимое которой соответствует свойству status, расположена слева и имеет относительно небольшие размеры (особенно в режимах видеоадаптера с низким разрешением). Это необходимо учитывать, если вы собираетесь использовать бегущую строку для привлечения внимания пользователя.

Свойства windows и self - синонимы. Вы можете применять любое их них по своему усмотрению.

Остальные свойства, в частности, свойства frames и length, применяются в том случае, когда в окно загружен документ HTML с фреймами. Анализируя свойство length вы можете определить количество фреймов в окне, а при помощи свойства frames (которое является массивом) нетрудно получить доступ к окнам этих фреймов. Работе с фреймами в сценариях JavaScript мы посвятим отдельную главу нашей книги.



Tan


Вычисление тангенса.

Пример использования:

var nValue;

nValue = Math.tan(nAngle);



Текстовые строки


Текстовые строки - это последовательность символов Unicode, заключенных в одинарные или двойные кавычки, например:

“Hello, world!”

“”

“12345”

‘Это текстовая строка’

Строка “” - пустая. Заметим, что следующие два присвоения не эквивалентны:

szStr=””

szStr1=null

В первом случае в переменной szStr хранится текстовая строка (хотя бы и пустая), во втором - совсем ничего.



Типы данных


Хотя при создании переменной вы не можете присвоить ей тип, в языке JavaScript все же существует несколько типов данных. Это числа, текстовые строки, логические данные, объекты, данные неопределенного типа, а также специальный тип null. Объекты мы рассмотрим позже, а сейчас расскажем об основных типах данных.



ToGMTString


Метод toGMTString предназначен для преобразования даты в строку, записанную в стандартном формате времени по Гринвичу (GMT).



ToLocaleString


Аналогично предыдущему, однако вместо времени GMT используется локальное время.



Три типа объектов JavaScript


В языке JavaScript имеется три типа объектов: встроенные объекты, объекты браузера и объекты, которые программист создает самостоятельно (рис. 2.1).

Рис. 2.1. Объекты в сценариях JavaScript

Каждый из этих типов имеет свое назначение и свои особенности.



Удаление cookie


Самый простой способ удалить cookie - установить для него такое время автоматического удаления, которое уже прошло. Для этого нужно получить текущую дату, уменьшить ее, например, на одну микросекунду, а затем изменить значение document.cookie.

Все это делает функция removeCookie:

function removeCookie(szName)

{

  var dtExpires = new Date();

  dtExpires.setTime(dtExpires.getTime() - 1);

  var szValue = findCookie(szName);

  document.cookie = szName + "=" + szValue +

    "; expires=" + dtExpires.toGMTString();

}

В последней строке этой функции мы указали такое значение параметра expires, которое вызывает немедленное удаление cookies браузером.



Унарные операторы


Унарные операторы применяются для изменения знака, выполнения операции дополнения, инкремента и декремента:

Унарный оператор

Назначение

-

Изменение знака на противоположный

!

Дополнение. Используется для реверсирования значения логических переменных

++

Увеличение значения переменной. Может применяться как префикс переменной или как ее суффикс

--

Уменьшение значения переменной. Может применяться как префикс переменной или как ее суффикс

Вот примеры использования унарных операторов:

i=0;      // начальное значение переменной i равно 0

i++;      // значение i равно 1

--i;      // значение i снова равно 0

var j=3;  // значение переменной j равно 3

i = -j;   // значение переменной i равно -3

var fYes = true; // значение переменной fYes равно true

testFlag(!fYes); // функции testFlag передается

                 //    значение false



Условные операторы


Любой язык программирования был бы бесполезен, если бы в нем не были предусмотрены те или иные средства ветвления при выполнении программы. В языке JavaScript предусмотрен условный оператор else-if, который позволяет выполнять разные программные строки в зависимости от условия.

Общий вид оператора else-if представлен ниже:

if(условие)

  строка 1

[else

 

строка 2]

Часть оператора, выделенная квадратными скобками, является необязательной. При выполнении этого оператора оценивается условие, заданное в круглых скобках после ключевого слова if. Если в результате оценки условия получилось логическое значение true, выполняется строка 1. Если же получилось значение false, то выполняется строка 2 (в том случае, когда она присутствует.

Оператор if-else может быть вложенным. Учтите, что если в строке 1 или строке 2 необходимо расположить несколько операторов, их следует выделить фигурными скобками:

if(nYourAge < 18)

{

  bAccessDenied = true;

  szNextPage = “bye18.html”;

}

else if(nYourAge > 99)

{

  bAccessDenied = true;

  szNextPage = “bye99.html”;

}

else

{

  bAccessDenied = false;

  szNextPage = “welcome.html”;

}

Здесь вначале оценивается условие (nYourAge < 18). Если содержимое переменной nYourAge меньше 18, переменной bAccessDenied присваивается значение true, а переменной szNextPage - текстовая строка “bye18.html”.

Затем содержимое nYourAge сравнивается с числом 99. Если переменная nYourAge имеет значение, большее чем 99, в переменную bAccessDenied записывается значение true, а переменную szNextPage - текстовая строка “bye99.html”.

И, наконец, если ни одно из двух условий не было выполнено, то есть значение переменной nYourAge находится в интервале от 18 до 99, в переменную bAccessDenied записывается значение false, а переменную szNextPage - текстовая строка “welcome.html”.

Существует также специальный тип условного оператора, который называется оператором ?:. Этот оператор в общем виде записывается так:

выражение ? строка 1 : строка 2

При вычислении оператора ?: вначале оценивается логическое выражение, расположенное в левой части. Если оно равно true, выполняется строка 1, а если false - строка 2.


Ниже мы привели пример использования условного оператора ?: для присвоения значения переменной bAccessDenied в зависимости от содержимого переменной nYourAge:

bAccessDenied =

  (nYourAge < 18 nYourAge > 99) ? true : false;

Если значение переменной nYourAge находится в интервале от 18 до 99, переменной bAccessDenied присваивается значение true, а если оно не попадает в этот интервал - false. Традиционное решение этой задачи с помощью оператора else-if заняло бы больше места:

if(nYourAge < 18 nYourAge > 99)

  bAccessDenied = true;

else

  bAccessDenied = false;

В приведенных выше примерах мы указывали составное условие:

(nYourAge < 18 nYourAge > 99)

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

((nYourAge < 18) (nYourAge > 99))


Установка и сброс точек останова


Сразу после запуска отладчика вы можете установить точки останова в текущем документе, загруженном в отладчик, или в другом произвольном документе, который загружен в браузер Microsoft Internet Explorer.

В открытом документе можно установить точки останова. Для этого запустите отладчик из браузера, воспользовавшись строкой Open и Break at next Statement меню View.

Затем вам нужно запустить сценарий. Это можно сделать, обновив документ в окне браузера или вызвав какое-либо событие, в результате которого сценарий получит управление.

Далее нужно поместить текстовый курсор на ту строку, где необходимо установить точку останова, а затем выбрать из меню Debug строку Toggle Breakpoint.

Строка, в которой находится точка останова, будет выделена красным цветом и отмечена красным кружочком, как это показано на рис. 8.6.

Рис. 8.6. Мы установили точку останова

При необходимости вы можете сбросить все или некоторые точки останова. Для сброса точки останова вы должны поместить в соответствующую строку текстовый курсор, а затем выбрать из меню Debug строку Toggle Breakpoint. Если нужно сбросить все точки останова, воспользуйтесь строкой Clear All Breakpoints из меню Debug.



Установка отладчика Microsoft Script Debugger


Процедура установки отладчика Microsoft Script Debugger очень проста. Если у вас уже установлен браузер Microsoft Internet Explorer, то вам достаточно запустить загруженный из Internet дистрибутивный файл. Единственно, о чем необходимо позаботиться, это чтобы версия отладчика Microsoft Script Debugger соответствовала версии браузера Microsoft Internet Explorer.

После установки вам необходимо убедиться, что установки параметров браузера разрешают отладку сценариев JavaScript. Для этого запустите Microsoft Internet Explorer, и из меню View выберите строку Internet Options. На экране появится одноименная диалоговая панель, показанная на рис.8.1.

Рис. 8.1. Диалоговая панель Internet Options

В этой панели вам нужно открыть страницу Advanced и выключить переключатель Disable script debugging, если он включен.



Установка закладок в исходном тексте


Еще одна возможность, которой обладает отладчик Microsoft Script Debugger, может оказаться особенно полезной при отладке больших сценариев, это закладки.

Вы можете установить закладку на любой строке исходного текста сценария, поместив в нее текстовый курсор и нажав комбинацию клавиш <Ctrl+F2>. Закладка будет отмечена небольшим квадратиком, как это показано на рис. 8.11.

Рис. 8.11. Установка закладки в исходном тексте сценария

Нажимая клавишу <F2> или комбинацию клавиш <Shift+F2> вы можете перемещаться по закладкам, соответственно, в прямом и обратном направлении.



UTC


Метод UTC преобразует дату, заданную параметрами метода, в количество миллисекунд, прошедшее с 1 января 1970 года.

При использовании метода UTC, так же как и метода parse, вам не нужно создавать объект класса Date:

nMillisecond =

  Date.UTC(year, month, date, hours, min, sec, ms);

Параметры метода UTC задаются таким же образом, как и описанные выше параметры конструктора объекта класса Date третьего вида.



Вариация четвертая: создание страницы “на лету”


Следующий сценарий имеет одну интересную особенность: в содержащем его документе HTML нет области <BODY> (листинг 1.5).

Листинг 1.5. Файл chapter1/HelloGen/HelloGen.html

<HTML>

  <HEAD>

    <SCRIPT LANGUAGE="JavaScript">

    <!--

      document.write("<TITLE>Hello, world!</TITLE>");

      document.write("<BODY BGCOLOR=white>");

      document.write("<H1>JavaScript Test</H1>");

      document.write("Hello, world!");

      document.write("</BODY>");

    // -->

    </SCRIPT> 

  </HEAD>

</HTML>

Если в предыдущем примере мы встраивали фрагменты сценария в область заголовка и в тело документа HTML, то сейчас весь сценарий находится в заголовке. Наш документ HTML не содержит ничего, кроме сценария JavaScript.

Когда такой документ загружается в окно браузера, программа JavaScript формирует недостающую часть заголовка (с помощью операторов <TITLE> и <TITLE>, а также тело документа.

Таким образом, сценарии JavaScript позволяют формировать все содержимое страницы динамически. Так как в языке JavaScript есть условные операторы, вы можете создавать разные страницы в зависимости от тех или иных обстоятельств. Например, определив тип и версию установленного у пользователя браузера, нетрудно сформировать для него страницу, учитывающую особенности конкретной версии приложения, с помощью которого пользователь просматривает ваш сервер Web.



Вариация первая: самый простая


На первом этапе мы составим программу JavaScript, которая вставит слова “Hello, world!” непосредственно в документ HTML (рис. 1.1).

Рис. 1.1. Внешний вид документа HTML с первой программой на  JavaScript

Как мы уже говорили, программы или сценарии JavaScript встраиваются в документ HTML. Взгляните на листинг 1.1, в котором мы привели исходный текст документа с нашей первой программой, составленной на JavaScript.

Листинг 1.1. Файл chapter1/hello/hello.html

<HTML>

  <HEAD>

    <TITLE>Hello, world!</TITLE>

  </HEAD>

  <BODY BGCOLOR=white>

    <H1>JavaScript Test</H1>

    <SCRIPT LANGUAGE="JavaScript">

    <!--

      document.write("Hello, world!");

    -->

    </SCRIPT>

  </BODY>

</HTML>

Как и подобает любому документу HTML, он ограничен операторами <HTML>, </HTML> и состоит из двух разделов. Раздел заголовка выделяется операторами <HEAD> и </HEAD>, а раздел тела документа - операторами <BODY BGCOLOR=white> и  </BODY>. В литературе операторы языка HTML часто называют тегами.

В заголовке нашего документа нет ничего необычного. Оператор <BODY BGCOLOR=white> устанавливает белый цвет фона документа, а операторы <H1> и </H1> задают стилевое оформление первой строки документа “JavaScript Test”, которая служит строкой заголовка первого уровня.

Что же касается собственно программы JavaScript, то в нашем первом примере она встроена в документ HTML при помощи операторов <SCRIPT> и </SCRIPT>, как это показано ниже:

<SCRIPT LANGUAGE="JavaScript">

<!--

  document.write("Hello, world!");

// -->

</SCRIPT>

С помощью оператора <SCRIPT> вы можете встроить в документ сценарий, составленный на языке JavaScript или VBScript. Язык указывается с помощью параметра LANGUAGE. Заметим, что для сценария на JavaScript допустимо указывать язык LiveScript - предок JavaScript. Такая возможность предусмотрена для обратной совместимости.


Текст сценария мы оформили как комментарий с применением операторов <!-- и -->. Это сделано для того чтобы наш сценарий не вызывал проблем у пользователей, браузеры которых не могут работать с JavaScript. Такие браузеры просто проигнорируют наш сценарий.

Обращаем также ваше внимание на строку, которой завершается комментарий:

// -->

Перед символами --> мы записали два символа /. Поясним, зачем это сделано.

Интерпретаторы языка JavaScript, встроенные в Microsoft Internet Explorer и Netscape Navigator, игнорируют символы -->, отмечающие начало комментария в документе HTML. Что же касается символов -->, то здесь поведение основных конкурирующих браузеров различается. Microsoft Internet Explorer игнорирует строку, состоящую только из символов -->, а Netscape Navigator рассматривает ее как ошибочную.

Для того чтобы обеспечить работоспособность нашего сценария в различных браузерах, мы добавили к строке --> два символа /, которые применяются в JavaScript для выделение комментариев наряду с известной из языка С конструкцией /*...*/.

Наша первая программа весьма проста и содержит только одну строку:

document.write("Hello, world!");

Здесь для объекта с именем document вызывается метод write. В качестве параметра ему передается текстовая строка "Hello, world!". Строка закрывается символом точка с запятой, хотя этот символ может и отсутствовать.

Объект document - это документ HTML, загруженный в окно браузера. Он содержит в себе объекты, свойства и методы, предназначенные для работы с элементами этого документа HTML, а также для взаимодействия с другими объектами.

Подробнее об этом мы расскажем позже, а сейчас отметим только, что метод write нашей программы записывает в тело документа HTML приветственную строку "Hello, world!". При этом документ будет выглядеть так, как будто эта строка находится в нем на месте сценария:

<HTML>

<HEAD>

<TITLE>Hello, world!</TITLE>

</HEAD>

<BODY BGCOLOR=white>

<H1>JavaScript Test</H1>

Hello, world!

</BODY>

</HTML>

Интерпретатор HTML, встроенный в браузеры, допускает использование в документах HTML строчных или прописных символов, не делая между ними различия. Однако интерпретатор JavaScript делает такие различия, поэтому составляя программу JavaScript, вы должны это учитывать.


Вариация пятая: с диалоговой панелью


Язык JavaScript имеет встроенные средства для отображения простейших диалоговых панелей, таких как панель сообщений (рис. 1.4).

Рис. 1.4. Диалоговая панель, которая появляется при загрузке страницы в браузер

В листинге 1.6 мы привели исходный текст сценария JavaScript, в котором вызывается функция alert, предназначенная для отображения диалоговых панелей с сообщениями.

Листинг 1.6. Файл chapter1/HelloBox/HelloBox.html

<HTML>

  <HEAD>

    <SCRIPT LANGUAGE="JavaScript">

    <!--

      document.write("<TITLE>Hello, world!</TITLE>");

      document.write("<BODY BGCOLOR=white>");

      document.write("<H1>JavaScript Test</H1>");

      alert("Hello, world!");     

      document.write("</BODY>");

    // -->

    </SCRIPT> 

  </HEAD>

</HTML>

Для продолжения загрузки страницы необходимо нажать кнопку OK. Только после этого содержимое страницы (состоящее в данном случае из одной строки заголовка) появится на экране.

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



Вариация седьмая: с определением типа браузера


Последний пример сценария, который мы рассмотрим в этом разделе, показывает, как программа JavaScript может легко определить тип и версию браузера. На рис. 1.6 показан результат просмотра документа HTML с этим сценарием при помощи браузера Microsoft Internet Explorer.

Рис. 1.6. Информация о браузере Microsoft Internet Explorer

То, что вы увидите, просмотрев этот же документ браузером Netscape Navigator, представлено на рис. 1.7.

Рис. 1.7. Информация о браузере Netscape Navigator

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

Листинг 1.8. Файл chapter1/HelloInfo/HelloInfo.html

<HTML>

  <HEAD>

    <TITLE>Hello, world!</TITLE>

  </HEAD>

  <BODY BGCOLOR=white>

    <H1>Something about you...</H1>

    <TABLE>

    <SCRIPT LANGUAGE="JavaScript">

    <!--

      document.writeln("<TR><TD>Navigator Name:</TD><TD>"

        + navigator.appName.bold() + "</TD></TR>");

      document.writeln("<TR><TD>Navigator Code Name:</TD><TD>"

        + navigator.appCodeName.bold() + "</TD></TR>");

      document.writeln("<TR><TD>Navigator version:</TD><TD>"

        + navigator.appVersion.bold() + "</TD></TR>");

      document.writeln("<TR><TD>User agent:</TD><TD>"

        + navigator.userAgent.bold() + "</TD></TR>");

    // -->

    </SCRIPT>

    </TABLE>

  </BODY>

</HTML>

Здесь сценарий JavaScript формирует в документе HTML строки таблицы, записывая в них названия различных свойств объекта navigator и значения, соответствующие этим свойствам.

Объект navigator - это сам браузер. Обращаясь к свойствам этого объекта,  можно получить различную информацию о браузере.

Наиболее интересны для нас свойства  navigator.appName и navigator.appVersion, так как они позволяют однозначно определить тип браузера и его версию. Обладая этой информацией, вы можете динамически “приспособить” документ HTML к навигатору, установленному у пользователя.

Заметим, что в браузере Microsoft Internet Explorer реализован еще один метод определения версии браузера, который мы рассмотрим позже. К сожалению, этот метод несовместим с браузером Netscape Navigator.



Вариация шестая: обработка события


В языке JavaScript есть удобные средства обработки событий. В нашем следующем примере когда пользователь пытается выбрать ссылку “Select me!” (рис. 1.5), разместив над ней курсор мыши, на экране появляется диалоговая панель Microsoft Internet Explorer с сообщением “Hello, world!”.

Рис. 1.5. Диалоговая панель появляется, когда пользователь размещает курсор мыши над ссылкой

Исходный текст соответствующего документа HTML с встроенным в него сценарием представлен в листинге 1.7.

Листинг 1.7. Файл chapter1/HelloOnSelect/HelloOnSelect.html

<HTML>

  <HEAD>

    <TITLE>Hello from JavaScript!</TITLE>

  </HEAD>

  <BODY BGCOLOR=white>

    <H1>JavaScript Test</H1>

    <HR>

    <A HREF="" onMouseover="alert('Hello, world!');">Select me!</A>

  </BODY>

</HTML>

Здесь для нас интересна строка оператора <A>. Напомним, что этот оператор обычно применяется для организации ссылок на другие документы HTML или файлы различных объектов. В данном случае поле ссылки параметра HREF пустое, однако дополнительно в оператор <A> включена следующая конструкция:

onMouseover="alert('Hello, world!');"

Она указывает, что при возникновении события onMouseover должна выполняться следующая строка программы JavaScript:

alert('Hello, world!');

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

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



Вариация третья: с переменной и функциями


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

Листинг 1.4. Файл chapter1/HelloFn/HelloFn.html

<HTML>

  <HEAD>

    <TITLE>Hello, world!</TITLE>

    <SCRIPT LANGUAGE="JavaScript">

    <!--

    var szHelloMsg = "Hello, world!";

    function printString(szString)

    {

      document.write(szString.bold());

    }

    function printHello()

    {

      printString(szHelloMsg);

    }

    // -->

    </SCRIPT>

  </HEAD>

  <BODY BGCOLOR=white>

    <H1>JavaScript Test</H1>

    <P>Message:

    <SCRIPT LANGUAGE="JavaScript">

    <!--

    printHello();

    // -->

    </SCRIPT> 

  </BODY>

</HTML>

Эта программа записывает в документ сообщение “Hello, world!”, выделяя его жирным шрифтом (рис. 1.3).

Рис. 1.3. Сообщение выделено жирным шрифтом

Рассмотрим исходный текст нашего документа HTML и встроенного в него сценария JavaScript.

Прежде всего, обратите внимание на область заголовка документа, выделенную операторами <HEAD> и </HEAD>. В этой области расположено определение одной переменной и двух функций, оформленное с применением операторов <SCRIPT> и </SCRIPT>:

<SCRIPT LANGUAGE="JavaScript">

<!--

  var szHelloMsg = "Hello, world!";

  function printString(szString)

  {

    document.write(szString.bold());

  }

  function printHello()

  {

    printString(szHelloMsg);

  }

// -->

</SCRIPT>

Кроме того, в теле документа HTML есть еще один раздел сценариев, выделенный аналогичным образом:

<SCRIPT LANGUAGE="JavaScript">

<!--

  printHello();

// -->

</SCRIPT> 

Переменная с именем szHelloMsg определяется при помощи оператора var, причем ей сразу же присваивается начальное значение - текстовая строка  "Hello, world!".


Заметим, что в отличие от Java, язык JavaScript не является типизированным. Это означает, что программист не может указать явным образом тип создаваемых им переменных. Этот тип определяется интерпретатором JavaScript автоматически, когда переменной в первый раз присваивается какое-либо значение. В дальнейшем вы можете легко изменить тип переменной, просто присвоив ей значение другого типа.

Отсутствие строгой типизации упрощает создание сценариев, особенно для непрофессиональных программистов, однако может привести к ошибкам. Поэтому мы рекомендуем вам внимательно следить за тем, какие типы данных вы применяете. Не исключено, что вам поможет использование префиксов имен, по которым можно судить о типе переменной. Эти префиксы хорошо знакомы программистам, создававшим приложения для операционной системы Microsoft Windows на языке программирования С. Например, текстовые строки можно начинать с префикса sz, а численные значения - с префикса n.

Помимо переменной szHelloMsg, в области заголовка документа HTML мы определили с помощью ключевого слова function две функции с именами printString и printHello. Первая из этих функций выводит в документ HTML строку, передаваемую ей в качестве параметра, а вторая выводит сообщение “Hello, world!”, вызывая для этого первую функцию.

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

Размещение определений переменных и функций в разделе заголовка документа гарантирует, что они будут загружены до момента загрузки тела документа.

Изучая приведенный в листинге 1.4 исходный текст, обратите внимание на функцию printString:

function printString(szString)

{

  document.write(szString.bold());

}

Здесь для объекта document вызывается метод write. В качестве параметра мы передаем этому методу объект szString, вызвав для него метод bold.

Значит, переменная szString, определенная с помощью ключевого слова var, является объектом?

После того как мы присвоили этой переменной значение текстовой строки, она стала объектом встроенного класса текстовых строк, для которого определены несколько методов. С помощью этих методов можно выполнять различные операции над текстовыми строками, такие как извлечение подстрок, преобразование символов из прописных в заглавные и обратно, наложение шрифтового оформления и так далее.

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

var szHelloMsg = "<B>Hello, world!</B>";

Однако в данном случая нам хотелось продемонстрировать возможность вызова методов для переменных типа текстовых строк.


Вариация вторая: с секретным исходным текстом


Как нетрудно догадаться, исходный текст нашего сценария, расположенный в документе HTML, легко доступен для просмотра любому пользователю, загрузившему этот документ в браузер. Чтобы ознакомиться с ним, достаточно выбрать в меню View строку Source (для браузера Microsoft Internet Explorer) или Document Source (для браузера Netscape Navigator).

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

Есть ли средство защитить исходные тексты ваших сценариев от просмотра, одновременно обеспечив их выполнение?

Если ваши пользователи работают с браузером Microsoft Internet Explorer версии 4.0 или с браузером Netscape Navigator, то есть. Это средство - параметр SRC оператора <SCRIPT>, допускающий указывать адрес URL файла сценария.

Наш следующий пример демонстрирует использование параметра SRC.

В листинге 1.2 находится исходный текст документа HTML, содержащий ссылку на файл сценария hello.js.

Листинг 1.2. Файл chapter1/SecretHello/SecretHello.html

<HTML>

  <HEAD>

    <TITLE>Secret Hello</TITLE>

  </HEAD>

  <BODY BGCOLOR=white>

    <H1>JavaScript Test No. 2</H1>

    <SCRIPT LANGUAGE="JavaScript" SRC="hello.js">

    </SCRIPT>

  </BODY>

</HTML>

Ссылка оформлена с применением операторов <SCRIPT> и </SCRIPT>, однако между этими операторами нет ни одной строчки исходного текста. Мы перенесли этот текст в файл hello.js (листинг 1.3).

Листинг 1.3. Файл chapter1/SecretHello/hello.js

document.write("<HR>");

document.write("Hello from JavaScript!");

document.write("<HR>");

В параметр SRC нашего примера задано только имя файла, так как он находится в том же каталоге, что и ссылающийся на него файл документа HTML. Однако вы можете указать и полный адрес URL, например:

<SCRIPT LANGUAGE="JavaScript" SRC="http://www.myserver.ru/scripts/hello.js">


Существенно, чтобы файл, в котором находится исходный текст сценария JavaScript, имел тип js. В противном случае сценарий работать не будет.

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

В результате работы нашей второй программы в окне браузера Netscape Navigator появится строка "Hello from JavaScript!", выделенная сверху и снизу горизонтальными линиями (рис. 1.2).



Рис. 1.2. Результат работы сценария, записанного в отдельном файле

Конечно, жаль, что браузер Microsoft Internet Explorer версии 3.02 не распознает параметр SRC в операторе <SCRIPT>. Однако версия 4.0 успешно работает с данным параметром. Дело в том, что параметр SRC включен в новую спецификацию языка разметки гипертекста HTML версии 4.0. При разработке нового браузера Microsoft стремился обеспечить совместимость с этой спецификацией.

И, конечно, раз уже речь зашла про HTML версии 4.0, нельзя не упомянуть про то что при использовании оператора <SCRIPT> вместо параметра LANGUAGE рекомендовано указывать стандартный параметр TYPE в следующем виде:

<SCRIPT TYPE="text/javascript">

// строки сценария JavaScript

  . . .

</SCRIPT>

Этот способ работает в браузерах Microsoft Internet Explorer версии 3.02, 4.0 и Netscape Navigator версии 3.01.

Использовать ли вам параметр SRC при создании своих страниц?

Если вы создаете сервер в сети Internet, то необходимо учитывать тот факт, что пользователи применяют различные браузеры. Наибольшей популярностью по-прежнему пользуется браузер фирмы Netscape, однако доля владельцев бесплатного браузера Microsoft Internet Explorer стремительно растет. Кроме того, есть еще браузеры, работающие на платформе UNIX. На ваш сервер могут зайти даже такие пользователи, которые просматривает страницы серверов Web в текстовом режиме при помощи программы Lynx.

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

Лучшее решение заключается в том, чтобы сервер сам определял тип браузера пользователя, подстраиваясь автоматически под его возможности без лишних слов и вопросов. Эта, казалось бы, трудная задача, легко решается при помощи сценариев JavaScript, в чем вы еще сможете убедиться.


Встраивание аплета Java в документ HTML


Для того чтобы встроить аплет в документ HTML, вы должны воспользоваться оператором <APPLET>, например:

<APPLET

    CODE=MyApplet.class

    NAME=”MyApplet”

    ID=MyApplet

    WIDTH=320

    HEIGHT=240>

</APPLET>

Перечислим допустимые параметры оператора <APPLET>:

Параметр

Описание

ALIGN

Выравнивание окна аплета относительно окружающего его текста. Возможны следующие значения:

LEFT      выравнивание влево относительно окружающего текста;

CENTER               центрирование;

RIGHT    выравнивание вправо относительно окружающего текста;

TOP        выравнивание по верхней границе;

MIDDLE центрирование по вертикали;

BOTTOM                выравнивание по нижней границе

ALT

С помощью этого параметра можно задать текст, который будет отображаться в окне аплета в том случае, если браузер не может работать с аплетами Java

CODE

Имя двоичного файла, содержащего код аплета. По умолчанию путь к этому файлу указывается относительно каталога с файлом HTML, куда встроен аплет. Такое поведение может быть изменено параметром CODEBASE

CODEBASE

Базовый адрес URL аплета, то есть путь к каталогу, содержащему аплет

HEIGHT

Начальная ширина окна аплета в пикселах

WIDTH

Начальная высота окна аплета в пикселах

HSPACE

Зазор слева и справа от окна аплета

VSPACE

Зазор сверху и снизу от окна аплета

NAME

Имя аплета. Оно может быть использовано другими аплетами, расположенными в одном и том же документе HTML, а также сценариями JavaScript

TITLE

Строка заголовка

Дополнительно между операторами <APPLET> и </APPLET> вы можете задать параметры аплета. Для этого используется оператор <PARAM>.

Пользуясь операторами <PARAM>, расположенными в документе HTML сразу после оператора <APPLET>, можно передать аплету произвольное количество параметров, например, в виде текстовых строк:

<APPLET

CODE=MyApplet.class

    NAME=”MyApplet”

    ID=MyApplet

    WIDTH=320

    HEIGHT=240>

    <PARAM NAME=ParamName1 VALUE="Param Value 1">

    <PARAM NAME=ParamName2 VALUE="Param Value 2">

    <PARAM NAME=ParamName3 VALUE="Param Value 3">

    <PARAM NAME=ParamName4 VALUE="Param Value 4">

     . . .

</APPLET>

Здесь через параметр NAME оператора <PARAM> передается имя параметра аплета, а через параметр VALUE - значение соответствующего параметра.



Встроенные функции


В этом разделе мы перечислим несколько полезных встроенных функций, которые вы можете использовать в своих сценариях JavaScript.

eval

Функция eval предназначена для преобразования текстовой строки в численное значение. Через единственный параметр она получает текстовую строку и вычисляет ее как выражение языка JavaScript. Функция возвращает результат вычисления:

var nValue = Eval(szStr);

parseInt

Эта функция предназначена для преобразования текстовой строки в целочисленное значение. Строка передается функции через параметр:

var nValue = parseInt(szStr);

parseFloat

Функция parseFloat пытается преобразовать текстовую строку в число с плавающей точкой. Текстовая строка передается этой функции через первый параметр, а основание счисления - через второй:

var nFloat = parseFloat(szStr, nRadix);

escape

С помощью функции escape сценарий JavaScript может закодировать текстовую строку с применением URL-кодировки. В этой кодировке специальные символы, такие как пробел или символ табуляции, преобразуются к следующему виду: %XX, где XX - шестнадцатеричный код символа.

Вот пример использования этой функции:

var szURL = escape(szStr);

unescape

Функция unescape выполняет действие, прямо противоположное действию функции unescape - перекодирует строку из URL-кодировки в обычную текстовую строку:

var szStr = unescape(szURL);



Встроенные объекты


Ниже мы перечислили встроенные объекты, свойства и методы которых доступны в сценариях JavaScript без предварительного определения этих объектов:

Объект

Описание

Array*

Массив

Boolean*

Логические данные

Date

Календарная дата

Function*

Функция

Global*

Глобальные методы

Math

Математические константы и функции

Number*

Числа

Object*

Объект

String 

Строки

Здесь символом * отмечены встроенные объекты, определенные в языке Microsoft JScript версии 3.0. Эта версия реализована в браузере Microsoft Internet Explorer версии 4.0.

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

Как работать со встроенными объектами?

Достаточно просто. Программа создает реализации (instance) объектов, а затем обращается к свойствам и методам объектов.

В качестве примера, имеющего практическое значение, рассмотрим документ HTML, в котором отображается текущая дата и время. Исходный текст этого документа вы найдете в листинге 2.1.

Листинг 2.1. Файл chapter2/date/date.html

<HTML>

  <HEAD>

    <TITLE>Show date and time</TITLE>

  </HEAD>

  <BODY BGCOLOR=WHITE>

    <H1>Show date and time</H1>

    <SCRIPT LANGUAGE="JavaScript">

    <!--

      var dt;

      var szDate="";

      dt = new Date();

      szDate = "Date: " + dt.getDate() + "."

        + dt.getMonth() + "." + dt.getYear();

      document.write(szDate);

      document.write("<BR>");

      document.write("Time: " + dt.getHours()

        + ":" + dt.getMinutes() + ":" + dt.getSeconds());

    // -->

    </SCRIPT>

  </BODY>

</HTML>


Здесь сценарий JavaScript создает объект Data, применяя для этого ключевое слово new, знакомое всем поклонникам языка С++, и конструктор Date без параметров:

var dt;

dt = new Date();

Создаваемый таким образом объект Data инициализируется текущей локальной датой, установленной у пользователя (а не на сервере Web, с которого был загружен соответствующий документ HTML).

В следующей строке формируется текстовая строка даты:

szDate = "Date: " + dt.getDate() + "."

  + dt.getMonth() + "." + dt.getYear();

Значение календарного числа, номера месяца и года здесь получается при помощи методов getDate, getMonth и getYear, соответственно. Эти методы вызываются для объекта dt, содержащего текущую дату.

Текстовая строка даты выводится в документ HTML с помощью метода write, определенного в объекте document:

document.write(szDate);

Этот способ мы уже использовали в примерах сценариев, приведенных в первой главе нашей книги.

Заметим, что объект Date содержит также информацию о текущем времени. Эта информация извлекается для отображения с помощью методов getHours, getMinutes и getSeconds (соответственно, часы, минуты и секунды):

document.write("Time: " + dt.getHours()

  + ":" + dt.getMinutes() + ":" + dt.getSeconds());

Внешний вид документа HTML при его просмотре в окне браузера Microsoft Internet Explorer версии 4.0 показан на рис. 2.2.



Рис. 2.2. Просмотр локальной даты и времени

Применение других встроенных объектов мы продемонстрируем позже по мере изучения материала.


Встроенный класс Date


С помощью методов встроенного класса Date сценарий JavaScript может выполнять различные действия с часами компьютера, например, получать и устанавливать текущую дату и время. Ниже мы приведем краткое описание конструкторов и методов этого класса.



Встроенный класс Math


Хотя сценарии JavaScript редко применяют для математических вычислений, в нем все же есть встроенный класс Math, предназначенный как раз для этого. В этом классе есть очень полезные методы, которые мы будем применять в наших примерах.



Второй способ: создание cookie в сценарии JavaScript


Второй способ предполагает использование свойства document.cookie. Это свойство мы упомянули, рассказывая о свойствах и методах объекта document, создаваемого для документа HTML, загруженного в окно браузера.

В общем виде сценарий JavaScript может создать cookie следующим образом:

document.cookie =

  “Имя=Значение;

Здесь мы просто записываем в свойство cookie объекта document текстовую строку, определяющую cookie.

Для пересчета текущей даты в формат GMT в сценариях JavaScript можно использовать встроенные функции, о чем мы скоро расскажем.

В качестве примера приведем исходный текст функции addCookie, которую мы будем использовать в своих сценариях для создания cookie:

function addCookie(szName,szValue,dtDaysExpires)

{

   var dtExpires = new Date();

   var dtExpiryDate = "";

   dtExpires.setTime(dtExpires.getTime() +

     dtDaysExpires * 24 * 60 * 60 * 1000);

   dtExpiryDate = dtExpires.toGMTString();

   document.cookie =

    szName + "=" + szValue + "; expires=" + dtExpiryDate;

}

Функция addCookie получает три параметра.

Через параметр szName передается имя параметра, хранящегося в cookie. Параметр szValue определяет значение этого параметра cookie. Что же касается последнего параметра с именем dtDaysExpires, то он задает интервал времени по отношению к моменту создания cookie, когда этот cookie необходимо удалить.

Самое сложное в функции addCookie - это определение даты удаления cookie и преобразование этой даты в формат GMT. Данная задача решается следующим образом.

Прежде всего функция addCookie создает объект класса Date с помощью ключевого слова new:

var dtExpires = new Date();

Записанная таким образом в переменную dtExpires дата соответствует моменту вызова функции addCookie.

Далее с помощью метода getTime функция addCookie определяет текущую дату в миллисекундах и прибавляет к результату значение параметра dtDaysExpires, полученное функцией, умноженное на константу (24 * 60 * 60 * 1000):


dtExpires.getTime() + dtDaysExpires * 24 * 60 * 60 * 1000

Константа представляет собой количество часов в сутках, умноженное на количество минут в часе, затем на количество секунд в минуте, и, наконец, на количество миллисекунд в секунде.

Результат вычислений записывается при помощи метода setTime в переменную даты dtExpires. Теперь здесь хранится дата автоматического уничтожения cookie браузером. Осталось лишь преобразовать эту дату в формат GMT.

Такое преобразование нетрудно сделать с помощью специально предназначенного для этого метода toGMTString, возвращающего текстовую строку в нужном нам формате:

dtExpiryDate = dtExpires.toGMTString();

Теперь нам остается только сформировать текстовую строку определения cookie и записать ее в свойство document.cookie:

document.cookie =

  szName + "=" + szValue + "; expires=" + dtExpiryDate;

На этом создание cookie завершено.

Теперь, когда в вашем распоряжении есть функция addCookie, создание cookie представляет собой очень простую задачу. Например, в следующей строке мы создаем cookie с именем Count, значением 0, причем через 10 дней браузер автоматически удалит этот cookie:

addCookie("Count","0",10);

При необходимости использования других параметров cookie, таких как path или domain, вы можете немного дополнить текст функции addCookie. С этой задачей вы легко справитесь самостоятельно.


Ввод идентификатора и пароля


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

В форме регистрации новый пользователь должен ввести свой идентификатор, а также задать пароль (3.15).

Рис. 3.15. Форма для регистрации нового пользователя

В процессе ввода пароля легко допустить ошибку, поэтому обычно в системах регистрации требуется вводить новый пароль два раза. Если оба раза был введен одинаковый пароль, то он становится активным для данного пользователя.

Наш сценарий, обрабатывающий данные из формы, показанной на рис. 3.15, решает две задачи.

Во-первых, он преобразует символы идентификатора пользователя в прописные. Во-вторых, сценарий проверяет идентичность паролей, введенных в полях “Пароль” и “Проверка пароля”.

Если введенные пароли идентичны, то после нажатия на кнопку Complete пользователь увидит на экране диалоговую панель с введенным идентификатором и паролем (рис. 3.16).

Рис. 3.16. Диалоговая панель с идентификатором и паролем нового пользователя

Если пароли не совпадают, сценарий предлагает пользователю повторить ввод паролей (рис. 3.17).

Рис. 3.17. Приглашение для повторного ввода пароля

Исходный текст нашего документа HTML, регистрирующего новых пользователей, показан в листинге 3.6.

Листинг 3.6. Файл chapter3/password/password.html

<HTML>

  <HEAD>

    <TITLE>Ввод и проверка пароля</TITLE>

    <SCRIPT LANGUAGE="JavaScript">

    <!--

    function Complete()

    {

      if(Sel.pwd.value != Sel.pwd1.value)

        alert("Ошибка при вводе пароля\nПопробуйте еще раз"); 

      else   

      {

        var szId="";

        var szPwd="";

        szId = Sel.id.value;

        szPwd = Sel.pwd.value;

        alert("Регистрация выполнена:\n" + "ID=" +

          szId + "\nPassword=" + szPwd); 

      }

    }

    // -->

    </SCRIPT>


  </HEAD>

  <BODY BGCOLOR=white>

    <H1>Регистрация</H1>

    <FORM NAME="Sel">

      <TABLE>

       <TR><TD><B>Идентификатор:</B></TD><TD><INPUT TYPE="text"

        NAME="id" onChange="this.value=this.value.toUpperCase()"

        SIZE="20" ></TD></TR>

      <TR><TD><B>Пароль:</B></TD><TD><INPUT TYPE="password"

        NAME="pwd" SIZE="20"></TD></TR>

      <TR><TD><B>Проверка пароля:</B></TD><TD><INPUT TYPE="password"

        NAME="pwd1" SIZE="20"></TD></TR>

      </TABLE>

      <P>

      <TABLE>

        <TR><TD><INPUT TYPE="button" VALUE="Complete"

        onClick="Complete();"></TD>

        <TD><INPUT TYPE="reset" VALUE="Reset"></TD></TR>

      </TABLE>

    </FORM>

  </BODY>

</HTML>

Преобразование символов идентификатора пользователя выполняет обработчик события onChange, определенный для поля id типа text:

<INPUT TYPE="text" NAME="id"

  onChange="this.value=this.value.toUpperCase()" SIZE="20">

Это преобразование выполняет функция toUpperCase, которой мы уже пользовались раньше.

Что же касается проверки пароля, то этим занимается функция Complete, определенная в качестве обработчика события onClick для одноименной кнопки, предназначенной для посылки заполненной формы.

Вот исходный текст этой функции:

function Complete()

{

  if(Sel.pwd.value != Sel.pwd1.value)

    alert("Ошибка при вводе пароля\nПопробуйте еще раз"); 

  else   

  {

    var szId="";

    var szPwd="";

    szId = Sel.id.value;

    szPwd = Sel.pwd.value;

    alert("Регистрация выполнена:\n" + "ID=" +

      szId + "\nPassword=" + szPwd); 

  }

}

Если пользователь ввел разные пароли, значения свойств Sel.pwd.value и Sel.pwd1.value не совпадают. В этом случае функция Complete отображает диалоговую панель с сообщением об ошибке.

При совпадении паролей функция Complete извлекает значения идентификатора пользователя Sel.id.value и его пароля Sel.pwd.value, а затем отображает их на экране.


Выполнение основных операций с cookie


Рассмотрим основные операции с cookie, такие как создание cookie, получение и изменение значений параметров cookies, а также удаление cookie.



Выполнение сценария в непрерывном режиме


Если после остановки выполнения сценария выбрать из меню Debug строку Run, работа сценария будет продолжена. В этом режиме сценарий будет выполняться до тех пор, пока не будет достигнута точка останова или пока в процессе интерпретации не будет обнаружена ошибка.



Выполнение сценария в пошаговом режиме


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

Во-первых, вы можете выполнить один шаг сценария с трассировкой вызовов функций. Для этого из меню Debug нужно выбрать строку Step Into.

Во-вторых, можно выполнять вызываемые функции без трассировки, воспользовавшись строкой Step Over меню Debug.

И, наконец, в-третьих, можно выбрать из меню Debug строку Step Out. В этом случае останов произойдет на выходе из функции.



Вызов методов аплета Java из сценария JavaScript


Сценарий JavaScript может получить доступ к полям и методам аплетов, расположенных в документе HTML, адресуясь к аплетам как к элементам массива document.applets. Например, для доступа к первому аплету вы можете использовать строку document.applets[0]. Однако удобнее указывать имя аплета, заданное в параметре NAME оператора <APPLET>, например document.MyApplet.

В качестве примера покажем, как можно вызывать из сценария JavaScript методы аплета Rectangles, описанного нами в упомянутом выше 32 томе “Библиотеки системного программиста”. Этот аплет рисует в своем окне прямоугольники случайного размера, закрашенные случайным цветом.

Мы создали документ HTML, разместив в нем аплет Rectangles и форму с кнопками Start Animation и Stop Animation (рис. 6.1).

Рис. 6.1. Аплет Rectangles управляется кнопками с помощью сценария JavaScript

Сразу после загрузки документа в окне аплета запускается процесс анимации. Если нажать кнопку Stop Animation, рисование новых прямоугольников будет приостановлено. С помощью кнопки Start Animation можно возобновить процесс рисования.

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

Исходный текст документа HTML, содержащий аплет и форму с кнопками, представлен в листинге 6.1.

Листинг 6.1. Файл chapter6/Rectangles/Rectangles.html

<HTML>

  <HEAD>

    <TITLE>Rectangles</TITLE>

  </HEAD>

  <BODY>

    <HR>

    <APPLET

      CODE=Rectangles.class

      NAME="Rectangles"

      ID=Rectangles

      WIDTH=320

      HEIGHT=240 >

    </APPLET>

    <HR>

    <FORM>

      <INPUT TYPE="button" VALUE="Start Animation" onClick="document.Rectangles.start()">

      <INPUT TYPE="button" VALUE="Stop Animation" onClick="document.Rectangles.stop()">


    </FORM>

    <A HREF="Rectangles.java">The source.</a>

  </BODY>

</HTML>

Здесь параметр NAME оператора <APPLET> задает имя аплета как Rectangles.

Когда пользователь нажимает на кнопку Start Animation, управление получает обработчик события onClick, определенный следующим образом:

onClick="document.Rectangles.start()"

Этот обработчик вызывает метод start, определенный в аплете Rectangles. Этот метод запускает анимацию в окне аплета, если она была остановлена.

Аналогично, обработчик события onClick кнопки Stop Animation вызывает метод stop, также определенный в аплете Rectangles и предназначенный для остановки анимации:

onClick="document.Rectangles.stop()"

Исходный текст аплета Rectangles мы воспроизвели в листинге 6.2. Подробное описание этого аплета вы найдете в разделе “Приложение Rectangles” первой главы 32 тома “Библиотеки системного программиста”.

Листинг 6.2. Файл chapter6/Rectangles/Rectangles.java

// =========================================================

// Рисование прямоугольников в отдельной задаче

//

// (C) Фролов А.В, 1997, 1998

//

// E-mail: frolov@glas.apc.org

// WWW:    http://www.glasnet.ru/~frolov

//            или

//         http://www.dials.ccas.ru/frolov

// =========================================================

import java.applet.*;

import java.awt.*;

import java.util.*;

public class Rectangles extends Applet implements Runnable

{

  // Ссылка на задачу рисования прямоугольников

  Thread m_Rectangles = null;

  // -------------------------------------------------------

  // getAppletInfo

  // Метод, возвращающей строку информации об аплете

  // -------------------------------------------------------

  public String getAppletInfo()

  {

    return "Name: Rectangles\r\n" +

      "Author: Alexandr Frolov\r\n" +

      "E-mail: frolov@glas.apc.org" +

      "WWW:    http://www.glasnet.ru/~frolov" +



      "Created with Microsoft Visual J++ Version 1.0";

  }

  // -------------------------------------------------------

  // paint

  // Метод paint, выполняющий рисование в окне аплета

  // -------------------------------------------------------

  public void paint(Graphics g)

  {

    // Определяем текущие размеры окна аплета

    Dimension dimAppWndDimension = size();

   

    // Выбираем в контекст отображения желтый цвет

    g.setColor(Color.yellow);

   

    // Закрашиваем внутреннюю область окна аплета

    g.fillRect(0, 0,

      dimAppWndDimension.width  - 1,

      dimAppWndDimension.height - 1);

    // Выбираем в контекст отображения черный цвет

    g.setColor(Color.black);

    // Рисуем рамку вокруг окна аплета

    g.drawRect(0, 0,

      dimAppWndDimension.width  - 1,

      dimAppWndDimension.height - 1);

  }

  // -------------------------------------------------------

  // start

  // Метод вызывается при первом отображении окна аплета

  // -------------------------------------------------------

  public void start()

  {

    if (m_Rectangles == null)

    {

      m_Rectangles = new Thread(this);

      m_Rectangles.start();

    }

  }

 

  // -------------------------------------------------------

  // stop

  // Метод вызывается, когда окно аплета исчезает с экрана

  // -------------------------------------------------------

  public void stop()

  {

    if (m_Rectangles != null)

    {

      m_Rectangles.stop();

      m_Rectangles = null;

    }

  }

  // -------------------------------------------------------

  // run

  // Метод, который работает в рамках отдельной задачи

  // Он рисует в окне аплета прямоугольники случайного

  // цвета, размера и расположения

  // -------------------------------------------------------

  public void run()

  {

    // Получаем контекст отображения для окна аплета

    Graphics g = getGraphics();

    // Определяем текущие размеры окна аплета



    Dimension dimAppWndDimension = size();

    while (true)

    {

      int x, y, width, height;

      int rColor, gColor, bColor;

     

      // Выбираем случайным образом размеры

      // и расположение рисуемого прямоугольника

      x = (int)(dimAppWndDimension.width * Math.random());

      y = (int)(dimAppWndDimension.height * Math.random());

      width = (int)(dimAppWndDimension.width *

              Math.random()) / 2;

      height = (int)(dimAppWndDimension.height *

              Math.random()) / 2;

      

      // Выбираем случайный цвет для рисования

      // прямоугольника

      rColor = (int)(255 * Math.random());

      gColor = (int)(255 * Math.random());

      bColor = (int)(255 * Math.random());

      // Устанавливаем выбранный цвет в контексте

      // отображения

      g.setColor(new Color(rColor, gColor, bColor));

      // Рисуем прямоугольник

      g.fillRect(x, y, width, height);

      // Выполняем задержку на 50 миллисекунд

      try

      {

        Thread.sleep(50);

      }

      catch (InterruptedException e)

      {

        stop();

      }

    }

  }

  // -------------------------------------------------------

  // mouseEnter

  // Метод вызывается, когда курсор мыши оказывается над

  // окном аплета

  // -------------------------------------------------------

  public boolean mouseEnter(Event evt, int x, int y)

  {

    if (m_Rectangles != null)

    {

      // Когда курсор мыши оказывается над поверхностью

      // окна аплета, временно приостанавливаем

      // задачу рисования прямоугольников

      m_Rectangles.suspend();

    }

    return true;

  }

  // -------------------------------------------------------

  // mouseExit

  // Метод вызывается, когда курсор мыши покидает

  // окно аплета

  // -------------------------------------------------------

  public boolean mouseExit(Event evt, int x, int y)

  {

    if (m_Rectangles != null)

    {

      // Когда курсор мыши покидает окно аплета,

      // возобновляем работу задачи рисования

      // прямоугольников

      m_Rectangles.resume();

    }

    return true;

  }

}


Взаимодействие между фреймами


С помощью сценариев JavaScript вы можете наделить фреймы возможностями, недостижимыми с применением одного лишь только языка разметки гипертекста HTML. Например, один из фреймов может содержать ссылки на документы, которые при активизации этих ссылок загружаются в окно другого фрейма. Сценарий JavaScript позволит загружать таким образом не один документ, а одновременно несколько документов в разные фреймы. Пример организации такого взаимодействия мы рассмотрим немного позже, а сейчас на конкретном примере расскажем о том, как можно передавать данные между объектами форм, расположенных в разных фреймах.



Загрузка документа HTML в окно браузера


В разделе этой главы с названием “Открываем новое окно” мы рассказали вам о том, как сценарий JavaScript может открыть новое окно, загрузив в него документ HTML. Однако часто возникает и другая задача - отобразить новый документ HTML в текущем окне браузера, не создавая новое окно.

Наш следующий сценарий (листинг 2.7) решает как раз эту задачу.

Листинг 2.7. Файл chapter2/JumpTo/JumpTo.html

<HTML>

  <HEAD>

    <TITLE>Jump to other Web page</TITLE>

    <SCRIPT LANGUAGE="JavaScript">

    <!--

    function urlJump()

    {

      var szNewURL="";

      szNewURL=prompt("Enter new URL address:", "http://");

      window.location.href=szNewURL;

    }

    // -->

    </SCRIPT>

  </HEAD>

  <BODY BGCOLOR=white>

    <H1>Jump to other Web page</H1>

    <FORM NAME="selectForm">

      <P><INPUT TYPE="button" VALUE="Jump"

      onClick="urlJump();">

    </FORM>   

  </BODY>

</HTML>

Когда в пользователь нажимает кнопку Jump в форме selectForm (показанной на рис. 2.15), запускается функция urlJump.

Рис. 2.15. Кнопка Jump, предназначенная для перехода к просмотру другой страницы Web

Эта функция  вызывает метод prompt, определенный в классе window:

var szNewURL="";

szNewURL=prompt("Enter new URL address:", "http://");

Метод prompt отображает на окне монитора диалоговую панель, предназначенную для ввода текстовой строки. В нашем случае это должна быть строка адреса URL документа HTML, который будет загружен в окно браузера (рис. 2.16).

Рис. 2.16. Диалоговая панель для ввода нового адреса URL

Введенный адрес (на рис. 2.16 мы ввели адрес главной страницы нашего сервера Web) записывается в переменную szNewURL.

Теперь можно переходить к загрузке нового документа в окно браузера.

Когда мы рассказывали об объектах класса window, то говорили, что такие объекты содержат в себе другие объекты. В частности, объект window содержит в себе объект location, описывающий расположение документа HTML, загруженного в окно браузера.

Для того чтобы загрузить в окно новый документ, достаточно изменить содержимое свойства объекта location с именем href:

window.location.href=szNewURL;

Это свойство хранит адрес URL документа. Изменение содержимого свойства href объекта location главного окна браузера приводит к загрузке в это окно нового документа (рис. 2.17).

Рис. 2.17. В главное окно браузера загружен новый документ HTML



Записная книжка Cookies Notepad


В следующем примере мы применили cookie для хранения произвольного текста, набранного пользователем в многострочном окне редактирования (рис. 7.4).

Рис. 7.4. Документ с записной книжкой Cookies Notepad

При первой загрузке документа HTML с записной книжкой окно редактирования остается пустым. Вы можете набрать здесь любой текст и записать его в cookie, нажав кнопку Store text. Если теперь закрыть документ HTML и открыть его вновь, набранный вами ранее текст появится в окне редактирования.

Для того чтобы удалить текст и cookie, достаточно нажать кнопку Clear text.

Исходный текст документа HTML с записной книжкой Cookies Notepad представлен в листинге 7.2.

Листинг 7.2. Файл chapter7/Notebook/Notebook.html

<HTML>

  <HEAD>

    <TITLE>Cookies demo</TITLE>

    <SCRIPT LANGUAGE="JavaScript">

    <!--

    function addCookie(szName,szValue,dtDaysExpires)

    {

      var dtExpires = new Date();

      var dtExpiryDate = "";

      dtExpires.setTime(dtExpires.getTime() + dtDaysExpires * 24 * 60 * 60 * 1000);

      dtExpiryDate = dtExpires.toGMTString();

      document.cookie = szName + "=" + escape(szValue) + "; expires=" + dtExpiryDate;

    }

    function findCookie(szName)

    {

      var i = 0;

      var nStartPosition = 0;

      var nEndPosition = 0; 

      var szCookieString = document.cookie; 

      var szTemp = "";

      while (i <= szCookieString.length)

      {

        nStartPosition = i;

        nEndPosition = nStartPosition + szName.length;

        if(szCookieString.substring(nStartPosition,nEndPosition) == szName)

        {

          nStartPosition = nEndPosition + 1;

          nEndPosition = document.cookie.indexOf(";",nStartPosition);

          if(nEndPosition < nStartPosition)

            nEndPosition = document.cookie.length;

          szTemp = document.cookie.substring(nStartPosition,nEndPosition); 


          return unescape(szTemp);

          break;   

        }

        i++; 

      }

      return "";

    }

    function removeCookie(szName)

    {

      var dtExpires = new Date();

      dtExpires.setTime(dtExpires.getTime() - 1);

      var szValue = findCookie(szName);

      document.cookie = szName + "=" + szValue +

        "; expires=" + dtExpires.toGMTString();

    }

    function btnClick()

    {

      addCookie("MyText",TestForm.Comment.value,10);

    }

    // -->

    </SCRIPT>

  </HEAD>

  <BODY BGCOLOR=white>

    <H1>Cookies Notepad</H1>

    <FORM NAME="TestForm">

      <P><TEXTAREA NAME="Comment"

        ROWS="5" COLS="25" WRAP="physical">

      </TEXTAREA>

      <P><INPUT TYPE="button" VALUE="Store text"

      onClick="btnClick();">

      <INPUT TYPE="button" VALUE="Clear text"

      onClick="removeCookie('MyText');TestForm.Comment.value=''">

    </FORM>   

    <SCRIPT LANGUAGE="JavaScript">

    <!--

      var szMyText="";

      szMyText = findCookie("MyText");

      if(szMyText != "")

      {

        TestForm.Comment.value = szMyText;

      }

    // -->

    </SCRIPT>

  </BODY>

</HTML>

Функция addCookie, использованная нами в этом документе, имеет одну особенность: перед записью текстовой строки в параметр cookie она выполняет ее кодировку в формате URL, вызывая для этого функцию escape:

document.cookie = szName + "=" + escape(szValue) + "; expires=" + dtExpiryDate;

Это необходимо по той причине, что введенный в окне редактирования текст может содержать пробелы и любые другие символы.

Аналогичные изменения мы внесли и в функцию findCookie. Эта функция возвращает значение, перекодированное в обычный текст функцией unescape, выполняющей действия, обратные по отношению к функции escape:



szTemp = document.cookie.substring(

  nStartPosition,nEndPosition); 

return unescape(szTemp);

Когда пользователь нажимает кнопку Store text, вызывается функция btnClick:

function btnClick()

{

  addCookie("MyText",TestForm.Comment.value,10);

}

Эта функция просто записывает в параметр cookie с именем MyText текстовую строку, извлеченную из многострочного поля редактирования TestForm.Comment.value.

При удалении текста кнопкой Clear text вызывается функция removeCookie, удаляющая параметр cookie с именем 'MyText, а также записывается пустая строка в окно многострочного редактирования:

<INPUT TYPE="button" VALUE="Clear text"

  onClick = "removeCookie('MyText'); TestForm.Comment.value=''">

В самом конце тела документа HTML находится небольшой фрагмент сценария JavaScript, запускающийся сразу после загрузки этого документа:

var szMyText="";

szMyText = findCookie("MyText");

if(szMyText != "")

{

  TestForm.Comment.value = szMyText;

}

Этот фрагмент пытается получить значение параметра cookie с именем MyText. Если это ему удается и функция findCookie возвращает непустую строку, полученная строка записывается в окно многострочного поля редактирования TestForm.Comment.value.

В результате сразу после загрузки документа это окно оказывается заполненным текстом, сохраненным в cookie.

Вы можете посмотреть системный файл, хранящий данные cookie. Для этого откройте каталог Temporary Internet Files, расположенный в системном каталоге Microsoft Windows 95 или Microsoft Windows NT. Там должен быть файл и именем Notebook\. Вы можете скопировать этот файл, например, на поверхность рабочего стола и открыть для просмотра любым текстовым редактором. Вы увидите примерно это:

MyText

This%20is%20sample%20text.%0D%0A%u042D%u0442%u043E%20%u0442%u0435%u043A%u0441%u0442%2C%20%u043A%u043E%u0442%u043E%u0440%u044B%u0439%20%u044F%20%u043D%u0430%u0431%u0440%u0430%u043B%20%u0434%u043B%u044F%20%u043F%u0440%u0438%u043C%u0435%u0440%u0430.%0D%0A%0D%0A%u0410%u043B%u0435%u043A%u0441%u0430%u043D%u0434%u0440%20%u0424%u0440%u043E%u043B%u043E%u0432.

~~local~~/E:\JavaScript\Source\chapter7\Notebook\

0

642302464

29173566

2120102016

29171554

*

В самом начале файла видно имя MyText параметра cookie. На следующих строках до строки ~~local~~ расположено значение параметра MyText, соответствующее тексту, показанному на рис. 7.4.

Вслед за строкой ~~local~~ идет локальный адрес URL документа и другие параметры cookies, такие как дата, по достижению которой браузер удалит cookie.

Если удалить файл Notebook\ и затем открыть документ HTML, многострочное окно редактирования будет пустым. Удалив этот файл, мы удалим и расположенный в нем cookie.


Запуск отладчика через меню браузера


Для того чтобы запустить отладчик Microsoft Script Debugger через меню браузера, откройте меню View и выберите там меню второго уровня Script Debuger. В этом меню есть две строки: Open и Break at next Statement. Первая из них просто открывает окно отладчика, а вторая - запускает отладчик и останавливает сценарий на следующей строке. Вы можете попробовать оба режима, например, для одного из сценариев, приведенных нами в первой главе нашей книги.



Запуск сценария в режиме отладки


Мы рассмотрим три способа запуска сценария в режиме отладки. Первый из них предполагает встраивание команды вызова отладчика непосредственно в текст сценария. При втором способе запуск отладчика  выполняется из меню браузера Microsoft Internet Explorer. Третий способ - автоматический. Отладчик запускается автоматически, если в тексте сценария обнаружена ошибка.