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

         

Введение в JavaScript


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

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

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

Языки сценариев существовали давно. Они применялись, например, для автоматизации различных задач. В качестве примера можно привести язык сценариев UNIX, язык пакетных заданий MS-DOS или имеющий большее отношение к технологиям Internet язык Perl, предназначенный для создания программ CGI.

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

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


Заметим, что JavaScript не предназначен для создания сложных программ. Подобные задачи лучше решать с использованием других языков программирования, например, с помощью Java. Однако с помощью JavaScript вы можете быстро создавать активные страницы с достаточно сложным поведением. Этот язык несложен в изучении, а программы, составленные с его использованием, легко поддаются отладке.
Когда в наших томах “Библиотеки системного программиста” мы рассказывали о стандартах на язык HTML, то обращали ваше внимание на различия в реализации этого стандарта для браузеров Netscape Navigator и Microsoft Internet Explorer. А как обстоит дело с совместимостью в случае языка JavaScript?
К сожалению, не очень хорошо. Несмотря на то что новые версии Microsoft Internet Explorer “понимают” язык JavaScript, существуют различные особенности. Фактически в браузере Microsoft Internet Explorer реализован язык сценариев Jscript, который хотя и совместим с JavaScript, но эта совместимость не является полной. Причина, вероятно, заключается в том, что Microsoft продвигает другой язык сценариев с названием VBScript, произошедший от языка Visual Basic. Возможно, мы посвятим VBScript одну из наших следующих книг.

Классы и объекты в JavaScript


Язык сценариев JavaScript является объектно-ориентированным, подобно языку программирования С++, однако в реализации объектов между этими языками есть весьма существенные отличия.

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

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



Работа с формами


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

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





JavaScript и Фреймы


Для того чтобы работать сразу с несколькими документами HTML, можно предоставить пользователю многооконный интерфейс, реализованный при помощи фреймов. Подробно о фреймах мы рассказали в 29 томе “Библиотеки системного программиста”. Который называется “Сервер Web своими руками”.



Растровые изображения


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

К сожалению, возможности HTML не позволяют добиться достаточно сложных видеоэффектов без применения дополнительных средств, таких как аплеты Java, компоненты ActiveX и сценарии JavaScript. Фактически кроме статической графики вы можете использовать только анимационные изображения, построенные с применением многосекционных файлов GIF, и сегментированные графические изображения. Последние нужны для создания ссылок.

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



Взаимодействие с аплетами Java


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

Еще одна интересная возможность взаимодействия сценариев JavaScript с объектами документа HTML, которую мы рассмотрим в нашей книге, это связь сценариев и аплетов Java. Оказывается, из сценариев JavaScript вы можете обращаться к полям и методам аплетов Java.

Языку программирования Java мы посвятили 30 и 32 тома “Библиотеки системного программиста”, которые называются, соответственно, “Microsoft Visual J++. Создание приложений. Часть 1” и “Microsoft Visual J++. Создание приложений. Часть 2”. Перед тем как читать главу нашей книги “Взаимодействие с аплетами Java” мы рекомендуем вам ознакомиться с этими томами.



Применение COOKIE


Возможно, изучая настройки браузера вы сталкивались с таким понятием, как cookie.

Что это такое?

Скажем сразу, что с кулинарным искусством это связано мало, хотя некоторую аналогию все же можно провести. Говоря кратко, cookie представляет собой свойство документа HTML. Данные cookie физически хранятся локально на компьютере пользователя, загрузившего к себе этот документ, в виде специального системного файла. С помощью cookie пользователь может настроить, или “приготовить” по собственному вкусу документ HTML, если для него предусмотрена такая настройка.

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

Как мы уже говорили, основное, для чего нужно cookie - это для того, чтобы дать пользователю возможность настроить под свои потребности интерфейс активных документов HTML. Эти настройки могут анализироваться или не анализироваться сервером Web, но в любом случае они хранятся у пользователя. Настройки, разумеется, пропадут, если пользователь, скажем, отформатирует свой жесткий диск. После этого параметры настраиваемого документа HTML придется задавать заново.

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

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

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

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

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

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



Abs


Вычисление абсолютного значения.

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

var nValueAbs;

nValueAbs = Math.abs(nValue);

Здесь в переменную nValueAbs записывается абсолютное значение переменной nValue.



Acos


Вычисление арккосинуса.

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

var nValue;

nValue = Math.acos(nAngle);



Аннотация


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

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

Книга предназначена для всех, кто интересуется созданием физических или виртуальных серверов Web в сети Internet, а также в корпоративной сети Intranet. Она может быть полезна разработчикам справочно-информационных систем, ориентирующихся на технологии, связанные с применением HTML.



Asin


Вычисление арксинуса.

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

var nValue;

nValue = Math.asin(nAngle);



Atan


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

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

var nValue;

nValue = Math.atan(nAngle);



Автоматический запуск отладчика при возникновении ошибки


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

Вы можете попробовать этот режим на сценарии, представленном в листинге 8.2, куда мы намеренно внесли ошибку.

Листинг 8.2. Файл chapter8/error.html

<HTML>

  <HEAD>

    <TITLE>Hello, world!</TITLE>

    <SCRIPT LANGUAGE="JavaScript">

    <!--

    var szHelloMsg = "Hello, world!";

    function printHello()

    {

      // Строка с ошибкой

      document.Write(szHelloMsg.bold());

    }

    // -->

    </SCRIPT>

  </HEAD>

  <BODY BGCOLOR=white>

    <H1>JavaScript Test</H1>

    <P>Message:

    <SCRIPT LANGUAGE="JavaScript">

    <!--

    printHello();

    // -->

    </SCRIPT> 

  </BODY>

</HTML>

Сразу после запуска на экране появится диалоговая панель Internet Explorer Script Error, показанная на рис. 8.3.

Рис. 8.3. Сообщение об ошибке

Из текста сообщения ясно, что в седьмом по счету символе девятой строки документа HTML обнаружена ошибка: указанный в сценарии метод или свойство не определено для объекта.

Нажав кнопку Yes в панели Internet Explorer Script Error, будет запущен отладчик. Документ HTML с ошибкой будет загружен в окно отладчика, а текстовый курсор покажет ошибочную строку (рис. 8.4).

Рис. 8.4. Курсор указывает на строку с ошибкой



Авторский компакт-диск


В сентябре 1997 года в продаже появился авторский компакт-диск (как спецвыпуск журнала “Аурамедиа”), на котором вы можете найти наши первые книги серий “Библиотека системного программиста” и “Персональный компьютер. Шаг за шагом” в исходных текстах, дискеты ко всем книгам серии “Библиотека системного программиста”, статьи, написанные нами для периодических изданий, библиотеку программ FreeWare и ShareWare, ссылки на интересные ресурсы Internet, вернисаж художника Алексея Абрамкина и другую информацию.

Компакт-диск можно приобрести непосредственно в издательстве “Аурамедиа” и “Диалог-МИФИ”, а также по подписке.



Бегущий текст в строке состояния браузера


Решим одну очень распространенную задачу - отображение бегущего текста в строке состояния браузера (рис. 2.11).

Рис. 2.11. Бегущий текст в строке состояния браузера

Строка состояния обычно используется браузерами для отображения различной информации, например, информации о выполнении текущей операции. Для того чтобы записать что-нибудь в строку состояния, необходимо изменить содержимое свойства status объекта window окна браузера.

Эту задачу можно решить, например, так:

window.status = “Новая строка”;

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

В нашем сценарии (листинг 2.5) мы применим способ выполнения периодических процедур, основанный на использовании метода setTimeout, определенного для объекта window. Напомним, что этот метод позволяет организовать отложенное во времени выполнение команды, заданной первым параметром. Время, через которое команда будет запущена, указывается методу setTimeout вторым параметром.

Листинг 2.5. Файл chapter2/StatusScroll/StatusScroll.html

<HTML>

  <HEAD>

    <TITLE>Авторский компакт-диск</TITLE>

    <SCRIPT LANGUAGE="JavaScript">

    <!--

      var szMsg = "You are welcome to our Web site http://www.glasnet.ru/~frolov";

      var nSpace = 100;

      var nIteration = 0;

      function sscroll()

      {

        var cmd = "sscroll()";

        var szOut = ""; 

        var szText = "";

   

        for (i=0 ; i < nSpace ; i++)

        {   

          szText += " ";

        }

        szText += szMsg;

 

        szOut =

          szText.substring(nIteration, nSpace + nIteration);

        window.status = szOut;

 

        nIteration++;

        if(nIteration > nSpace + szMsg.length)

        {

          nIteration = 0;


        }

 

        timer = window.setTimeout(cmd, 50);

      }

    // -->

    </SCRIPT>

  </HEAD>

 

  <BODY BGCOLOR=white>

    <H1>Новый выпуск авторского CD</H1>

    <SCRIPT LANGUAGE="JavaScript">

    <!--

      sscroll();

    // -->

    </SCRIPT>

    <P>Первый выпуск нашего компакт-диска

уже появился в продаже. Информацию об этом, а также

следующем выпуске вы найдете на нашем сервере Web,

адрес которого отображается в окне состояния браузера

  </BODY>

</HTML>

В области заголовка документа мы определили глобальные переменные szMsg, nSpace и nIteration, а также функцию sscroll.

Переменная szMsg инициализируется текстовым сообщением, которое будет непрерывно перемещаться в строке состояния браузера. Значение, записанное в переменную nSpace, определяет количество пробелов, которое будет добавлено к строке сообщения слева перед началом операции сдвига. И, наконец, переменная nIteration служит счетчиком сдвигов для функции sscroll.

Функция sscroll вызывается первый раз в теле документа:

<BODY BGCOLOR=white>

  <H1>Новый выпуск авторского CD</H1>

  <SCRIPT LANGUAGE="JavaScript">

  <!--

    sscroll();

  // -->

  </SCRIPT>

  . . .

</BODY>

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

Упрощенно структура функции sscroll показана ниже:

function sscroll()

{

  var cmd = "sscroll()";

    . . .

  // Отображение сообщения в строке состояния браузера

    . . .

  // Сдвиг сообщения влево на одну позицию

    . . .

  timer = window.setTimeout(cmd, 50);

}

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



В качестве выполняемой команды мы указываем методу setTimeout вызов функции sscroll. Таким образом в нашем сценарии эта функция вызывается периодически.

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

Текстовая переменная szText используется как рабочая. В ней формируется сообщение для вывода.  Вначале в переменную szText записывается nSpace пробелов, а затем добавляется строка szMsg:

for (i=0 ; i < nSpace ; i++)

{   

  szText += " ";

}

szText += szMsg;

Для того чтобы при каждом вызове функции sscroll наше сообщение отображалось со сдвигом на одну позицию, мы извлекаем из переменной szText подстроку. Извлечение подстроки выполняется с помощью метода substring, определенного во встроенном классе текстовых строк String. Полученная подстрока записывается в свойство status объекта window и таким образом отображается в строке состояния:

szOut = szText.substring(nIteration, nSpace + nIteration);

window.status = szOut;

Первый параметр метода substring определяет начальную позицию подстроки внутри строки, а второй - конечную.

После отображения сообщения функция sscroll увеличивает значение глобального счетчика nIteration на единицу:

nIteration++;

Когда в результате сдвига сообщение полностью уходит из строки состояния, счетчик nIteration снова устанавливается в нулевое значение:

if(nIteration > nSpace + szMsg.length)

{

  nIteration = 0;

}

Обратите внимание, что общая длина сдвигаемой строки здесь вычисляется как сумма значения nSpace (количество начальных пробелов) и длины сообщения szMsg. Последняя определяется с помощью метода length, определенного во встроенном классе String.


Бинарные операторы


Бинарные операторы соединяют два операнда. В языке сценариев JavaScript предусмотрены бинарные операторы для вычитания, сложения, умножения, деления и вычисления остатка деления:

Бинарный оператор

Назначение

-

Вычитание

+

Сложение

*

Умножение

/

Деление

%

Вычисление остатка от деления

Эти операторы используются таким же образом, что и в языке программирования C, например:

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

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

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

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

k = j % 2;  // значение переменной i равно 1



Ceil


Вычисление наименьшего целого значения, большего или равного аргументу функции.

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

var nValue;

nValue = Math.ceil(nArg);



Числа


Язык сценариев JavaScript допускает использование чисел в различных форматах. Это целые числа, числа в формате с плавающей десятичной точкой и числа в научной нотации. Целые числа могут быть представлены по основанию 8, 10 или 16. Например:

Пример

Описание

25

Целое число по основанию 10

0137

Целое число по основанию 8

0xFF

Целое число по основанию 16

386.7

Число с плавающей десятичной точкой

25e5 или 25E5

Число в научной нотации, равно 2500000

В некоторых случаях арифметические функции могут возвращать так называемое “нечисло”, которое называется в JavaScript как NaN (Not a Number). “Нечисло” - это специальное значение, которое не соответствует никакому числу. Оно возникает в тех случаях, когда результат выполнения операции над числами не может быть представлен в виде числа. С помощью функции isNaN вы можете проверить, является ли значение “нечислом”.



Cos


Вычисление косинуса.

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

var nValue;

nValue = Math.cos(nAngle);



Цветовое оформление документа


Большинство свойств объекта objects доступно сценарию JavaScript как для чтения, так и для записи. Сначала мы попробуем динамически изменить цветовое оформление документа HTML, показанного на рис. 2.18.

Рис. 2.18. Документ HTML с цветовым оформлением, измененным при помощи сценария JavaScript

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

Листинг 2.8. Файл chapter2/ColorLinks/ColorLinks.html

<HTML>

  <HEAD>

    <TITLE>Color Links</TITLE>

    <SCRIPT LANGUAGE="JavaScript">

    <!--

      document.bgColor = "#00FF80";

      document.fgColor = "#800080";

      document.linkColor  = "#000000";

      document.alinkColor = "#FF0000";

      document.vlinkColor = "#4000FF";

    // -->

    </SCRIPT>

  </HEAD>

  <BODY BGCOLOR=white>

    <H1>Изменение цветового оформления</H1>

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

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

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

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

    <P><A HREF="ColorLinks.html#Локальный раздел">Локальный раздел</A>

    <HR>

    <H1><A NAME="Локальный раздел">Локальный раздел</A></H1>

    <P>Этот локальный раздел вы можете просмотреть, даже если ваш компьютер не подключен к Internet

  </BODY>

</HTML>

Обратите внимание, что наш сценарий переопределяет цвет фона, заданный параметром BGCOLOR в операторе <BODY>:

document.bgColor = "#00FF80";

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



Данные неопределенного типа


Если переменная была объявлена, но ей еще ни разу не присваивалось значение, она имеет неопределенный тип. Например, в следующей строке сценария объявлена переменная MyVariable, которая имеет неопределенный тип:

var MyVariable;

Если же этой переменной присвоить значение null, то тип переменной изменится - теперь это будет переменная, содержащая значение null:

MyVariable = null;



Десятично-шестнадцатеричный преобразователь


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

Рис. 4.1. Десятично-шестнадцатеричный преобразователь, выполненный с использованием фреймов

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

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

Исходный текст файла описания фреймов представлен в листинге 4.1.

Листинг 4.1. Файл chapter4/Converter/index.html

<HTML>

  <HEAD>

    <TITLE>Десятично-шестнадцатеричный   преобразователь</TITLE>

  </HEAD>

  <FRAMESET ROWS="85,*" FRAMEBORDER=1>

    <FRAME SCROLLING="no" NAME="title" SRC="title.html" MARGINHEIGHT="1">

    <FRAMESET COLS="180,*" FRAMEBORDER=1>

      <FRAME SCROLLING="auto" NAME="toc" SRC="toc.html">

      <FRAME SCROLLING="auto" NAME="mainpage" SRC="main.html">

    </FRAMESET>

    <NOFRAME>

      <BODY BGCOLOR="#FFFFFF">

      </BODY>

    </NOFRAME>

  </FRAMESET>

</HTML>

Наш сценарий будет работать с фреймами toc и mainpage, расположенными, соответственно, в файлах с именами toc.html и main.html. В файле title.html располагается заголовок (листинг 4.2).

Листинг 4.2. Файл chapter4/Converter/title.html

<HTML>

  <HEAD>

  <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=windows-1251">


  </HEAD>

  <BODY BGCOLOR="#ffffff">

    <TABLE><TR><TD>

      <H2>Десятично-шестнадцатеричный преобразователь</H2>

    </TD></TR></TABLE>

  </BODY>

</HTML>

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

Листинг 4.3. Файл chapter4/Converter/main.html

<HTML>

<HEAD>

<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=windows-1251">

</HEAD>

<BODY BGCOLOR="#FFFFFF">

    <FORM NAME="Sel">

      <TABLE>

       <TR><TD><B>Hex:</B></TD><TD><INPUT TYPE="text"

        NAME="hexValue" SIZE="20" onFocus="this.blur();"></TD></TR>

      <TR><TD><B>Dec:</B></TD><TD><INPUT TYPE="text"

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

    </FORM>

</BODY>

</HTML>

Для поля исходного десятичного числа при помощи параметра NAME мы задали имя decValue. Поле результата называется hexValue. Эти имена используются сценарием JavaScript для адресации наших полей.

Документ toc.html (листинг 4.4) содержит форму с кнопками и сценарий JavaScript.

Листинг 4.4. Файл chapter4/Converter/toc.html

<HTML>

<BODY BGCOLOR="#B0FFD8">

  <SCRIPT LANGUAGE="JavaScript">

  <!--

  var bNewNumber = true;

 

  function dec2hex(nDec)

  {

    var szHexTable="0123456789ABCDEF";

    var szResult = "";

    var szBuf="";

    var nRem = 0;

    var bNegative=false;

    if(nDec < 0)

    {

      bNegative=true;

      nDec = -nDec;

    }

    nTmp=nDec;

     

    while(true)

    {

      nRem = nTmp % 16;

      nTmp = nTmp / 16;

      if(Math.floor(nTmp) < 16)

        break;



      szBuf=szHexTable.charAt(nRem);

      szResult = szBuf.concat(szResult);

      nTmp = Math.floor(nTmp);

    }

   

    szBuf=szHexTable.charAt(nRem);

    szResult = szBuf.concat(szResult);

    if(Math.floor(nTmp) != 0)

    {

      szBuf=szHexTable.charAt(Math.floor(nTmp));

      szResult = szBuf.concat(szResult);

    }

    if(bNegative == true)

      return ("-" + szResult);

    else

      return szResult;

  }

  function putNumber(btn,form)

  {

    var szOld = "";

    var szNew = "";

    if(bNewNumber)

    {

      parent.mainpage.document.forms[0].hexValue.value = "";

      parent.mainpage.document.forms[0].decValue.value = "";

      bNewNumber = false; 

    }

   

    szOld = parent.mainpage.document.forms[0].decValue.value;

  

    szNew = szOld.concat(btn.name);

    nCurrent = eval(szNew);

  

    parent.mainpage.document.forms[0].decValue.value = nCurrent;

  }

  function clearAll(form)

  {

    total = 0; 

    lastOperation = "+"; 

    parent.mainpage.document.forms[0].hexValue.value = "0";

    parent.mainpage.document.forms[0].decValue.value = "0";

    bNewNumber = true; 

  }

  function getResult(form)

  {

    parent.mainpage.document.forms[0].hexValue.value = dec2hex(parent.mainpage.document.forms[0].decValue.value);

    bNewNumber = true;

  }

  // -->

  </SCRIPT>

  <FORM>

    <TABLE BORDER=2 BORDERCOLOR="Black" BGCOLOR="Yellow">

      <TR>

        <TD ALIGN=CENTER><INPUT TYPE="button" NAME="5" VALUE=" 5 " onClick="putNumber(this,this.form);"></TD>

        <TD ALIGN=CENTER><INPUT TYPE="button" NAME="6" VALUE=" 6 " onClick="putNumber(this,this.form);"></TD>

        <TD ALIGN=CENTER><INPUT TYPE="button" NAME="7" VALUE=" 7 " onClick="putNumber(this,this.form);"></TD>



        <TD ALIGN=CENTER><INPUT TYPE="button" NAME="8" VALUE=" 8 " onClick="putNumber(this,this.form);"></TD>

        <TD ALIGN=CENTER><INPUT TYPE="button" NAME="9" VALUE=" 9 " onClick="putNumber(this,this.form);"></TD>

      </TR>

      <TR>

        <TD ALIGN=CENTER><INPUT TYPE="button" NAME="0" VALUE=" 0 " onClick="putNumber(this,this.form);"></TD>

        <TD ALIGN=CENTER><INPUT TYPE="button" NAME="1" VALUE=" 1 " onClick="putNumber(this,this.form);"></TD>

        <TD ALIGN=CENTER><INPUT TYPE="button" NAME="2" VALUE=" 2 " onClick="putNumber(this,this.form);"></TD>

        <TD ALIGN=CENTER><INPUT TYPE="button" NAME="3" VALUE=" 3 " onClick="putNumber(this,this.form);"></TD>

        <TD ALIGN=CENTER><INPUT TYPE="button" NAME="4" VALUE=" 4 " onClick="putNumber(this,this.form);"></TD>

       </TR>

      <TR>

        <TD ALIGN=CENTER><INPUT TYPE="button" NAME="C" VALUE=" C " onClick="clearAll(this.form);"></TD>

        <TD COLSPAN=4 ALIGN=CENTER><INPUT TYPE="button" NAME="=" VALUE=" to Hex " onClick="getResult(this.form);"></TD>

      </TR>

    </TABLE>

  </FORM>

</BODY>

</HTML>

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



Для того чтобы проинициализировать поля hexValue и decValue, мы ссылаемся на форму, расположенную внутри фрейма mainpage:

parent.mainpage.document.forms[0].hexValue.value = "";

parent.mainpage.document.forms[0].decValue.value = "";

Здесь parent ссылается на объект, который является родительским по отношению к документу HTML, содержащему сценарий. В данном случае это окно, содержащее все наши фреймы.

Для чтения содержимого поля decValue применяется аналогичная техника:

szOld = parent.mainpage.document.forms[0].decValue.value;

Функция getResult, выполняющая десятично-шестнадцатеричное преобразование, получает исходное число из поля decValue и передает его функции dec2hex . Результат преобразования, выполненного этой функцией, записывается затем в поле hexValue:

function getResult(form)

{

  parent.mainpage.document.forms[0].hexValue.value = dec2hex(parent.mainpage.document.forms[0].decValue.value);

  bNewNumber = true;

}


Динамическая загрузка аплетов Java


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

Идея динамической загрузки аплетов заключается в том, что сценарий JavaScript динамически создает документ HTML, в котором находится оператор <APPLET>. Передавая аплету в этом документе различные значения параметров с помощью оператора <PARAM>, сценарий JavaScript может управлять его работой.

На рис. 6.3 мы показали документ HTML, состоящий из двух фреймов.

Рис. 6.3. Строка в окне аплета и ее шрифтовое оформление зависят от положения переключателей в левом фрейме

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

Займемся описанием исходных текстов нашего документа HTML.

В файле Index.html (листинг 6.6) находится описание фреймов.

Листинг 6.6. Файл chapter6/FrameLoad/Index.html

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">

<HTML>

  <HEAD>

    <TITLE>Динамическая загрузка аплетов</TITLE>

  </HEAD>

  <FRAMESET COLS="180,*" FRAMEBORDER=1>

    <FRAME SCROLLING="auto" NAME="toc" SRC="toc.html">

    <FRAME SCROLLING="auto" NAME="mainpage" SRC="main.html">

    <NOFRAME>

      <BODY BGCOLOR="#FFFFFF">

      </BODY>

    </NOFRAME>

  </FRAMESET>

</HTML>

Левый фрейм называется toc, а правый - mainpage.

Исходный текст документа для фрейма toc мы привели в листинге 6.6.

Листинг 6.6. Файл chapter6/FrameLoad/toc.html

<HTML>

  <BODY BGCOLOR="#B0FFD8">

    <SCRIPT LANGUAGE="JavaScript">

    <!--


      var szFont="Arial";

      function chkRadio(form,value)

      {

        szFont = value;

      }

    // -->

    </SCRIPT>

    <FORM>

      <B>Font:</B><BR>

      <INPUT TYPE="radio" NAME="font" VALUE="Arial" CHECKED

         onClick="if(this.checked) {chkRadio(this.form,this.value);}"> Arial<BR>

      <INPUT TYPE="radio" NAME="font" VALUE="Courier"

         onClick="if(this.checked) {chkRadio(this.form,this.value);}"> Courier<BR>

      <INPUT TYPE="radio" NAME="font" VALUE="TimesRoman"

         onClick="if(this.checked) {chkRadio(this.form,this.value);}"> TimesRoman<BR>

      <INPUT TYPE="radio" NAME="font" VALUE="Helvetica"

         onClick="if(this.checked) {chkRadio(this.form,this.value);}"> Helvetica<BR>

      <P>

      <INPUT TYPE=button VALUE="Show Applet"

         onClick="parent['mainpage'].location='main.html';">

    </FORM>

  </BODY>

</HTML>

Для работы с переключателями типа radio мы использовали уже знакомую вам методику. Обработчик события onClick проверяет, находится ли переключатель во включенном состоянии. Если это так, обработчик вызывает функцию chkRadio, передавая ей ссылку на форму и значение свойства value, соответствующее включенному переключателю.

Функция chkRadio сохраняет это значение в переменной szFont:

function chkRadio(form,value)

{

  szFont = value;

}

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

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

onClick="parent['mainpage'].location='main.html';"



Он устанавливает свойство location фрейма mainpage (то есть правого фрейма), присваивая ему адрес документа main.html. Исходный текст этого документа приведен в листинге 6.7.

Листинг 6.7. Файл chapter6/FrameLoad/main.html

<HTML>

  <BODY BGCOLOR="#FFFFFF">

    <SCRIPT LANGUAGE="JavaScript">

    <!--

      var szFont = parent.toc.szFont;

      document.write("<APPLET CODE=TextOut.class ID=TextOut WIDTH=300 HEIGHT=140 >");

      document.write("<param name=Str1 value='" + szFont + "'>");

      document.write("<param name=Font1 value='" + szFont + "'>");

      document.write("<param name=Type1 value='Plain'>");

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

    // -->

    </SCRIPT>

  </BODY>

</HTML>

Тело документа main.html содержит только сценарий JavaScript. Этот сценарий динамически создает строки оператора <APPLET> с параметрами Str1, Font1 и Type1.

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

var szFont = parent.toc.szFont;

Параметр Font1 задает шрифт для текста, отображаемого в окне аплета. Этот параметр также задается с использованием названия шрифта, выбранного в левом фрейме:

document.write("<param name=Font1 value='" + szFont + "'>");

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

Исходный текст аплета Java, использованного в нашем примере, приведен в листинге 6.8. Это упрощенный вариант алпета, описанного нами в 30 томе “Библиотеки системного программиста” в разделе “Приложение TextOut третьей главы.

Листинг 6.8. Файл chapter6/FrameLoad/TextOut.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.*;

public class TextOut extends Applet

{

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

  // Поля класса.

  // Создаются автоматически для всех параметров аплета

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

  private String m_Str1 = "Hello 1";

  private String m_Font1 = "Arial";

  private String m_Type1 = "Bold";

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

  // Имена параметров

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

  private final String PARAM_Str1 = "Str1";

  private final String PARAM_Font1 = "Font1";

  private final String PARAM_Type1 = "Type1";

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

  // getAppletInfo

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

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

  public String getAppletInfo()

  {

    return "Name: TextOut\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";

  }

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

  // getParameterInfo

  // Метод, возвращающий описание параметров

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

  public String[][] getParameterInfo()

  {

    String[][] info =

    {

      { PARAM_Str1, "String", "Text string to write" },

      { PARAM_Font1, "String", "Text font" },

      { PARAM_Type1, "String", "Font type" },



    };

    return info;   

  }

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

  // init

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

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

  public void init()

  {

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

    String param;

    // Получение параметров и сохранение

    // их значений в полях класса

    // Строки, которые будут выведены в окно аплета

    param = getParameter(PARAM_Str1);

    if (param != null)

      m_Str1 = param;

    // Шрифты для отображения строк

    param = getParameter(PARAM_Font1);

    if (param != null)

      m_Font1 = param;

    // Начертание шрифтов

    param = getParameter(PARAM_Type1);

    if (param != null)

      m_Type1 = param;

  }

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

  // paint

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

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

  public void paint(Graphics g)

  {

    // Начальная координата для вывода по вертикали

    int yStart   = 20;

    // Текущая координата для вывода строки

    int yCurrent = 20;

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

    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);

    // Получаем стиль шрифта и выбираем шрифт

    // в соответствии с этим стилем

    if(m_Type1.equals("Bold"))

      g.setFont(new Font(m_Font1, Font.BOLD, 25));

    else if(m_Type1.equals("Italic"))

      g.setFont(new Font(m_Font1, Font.ITALIC, 25));

    else if(m_Type1.equals("Plain"))

      g.setFont(new Font(m_Font1, Font.PLAIN, 25));

    // Отступ для первой строки

    yCurrent += yStart;

    // Рисуем первую строку

    g.drawString(m_Str1, 10, yCurrent);

  }

}


Динамическая замена растровых изображений


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

Например, в следующей строке сценария JavaScript мы указываем, что изображение с именем btn1 должно иметь адрес URL pic/aurap.gif:

document.btn1.src=”pic/aurap.gif”

Здесь мы указали неполный адрес URL, однако можно указывать и полный адрес.

Что произойдет при выполнении приведенной выше строки сценария?

Область, выделенная в окне браузера для растрового изображения btn1 будет заполнена изображением pic/aurap.gif. Если до этого там было другое изображение, оно будет заменено на новое.

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

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

Во-вторых, с помощью замены растровых изображений в сценарии JavaScript можно создавать анимационные изображения.

Рассмотрим примеры сценариев, решающих указанные задачи.



Динамическое заполнение списка


Сценарий JavaScript может изменять список, добавляя в него новые элементы. Пример такого сценария мы уже приводили в разделе второй главы с названием “Ссылки и метки в документе”. Мы предлагаем вам обратиться к этому разделу еще раз.

Напомним, что там мы создали в документе HTML пустой список с именем ListOfLinks, расположив его в форме Sel:

<FORM NAME="Sel">

      <SELECT NAME="ListOfLinks">

      </SELECT>

      <INPUT TYPE="button" VALUE="Jump!"  

         onClick="urlJump();">

</FORM>

Перед заполнением этого списка мы создали массив элементов elem:

elem = new Array();

Заполнение этого массива выполнялось в цикле, причем для создания элемента массива мы вызывали конструктор Option, задавая для него четыре параметра:

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

Первый параметр задает текст, который отображается в списке, второй - значение, назначаемое элементу списка при помощи параметра VALUE. Третий и четвертый параметры соответствуют свойствам, соответственно, defaultSelected и selected.

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

После того как элемент списка создан как объект класса option, его нужно записать в соответствующий элемент массива options:

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

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

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

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

function urlJump()

{

  var szNewURL="";

  szNewURL =       

    document.links[Sel.ListOfLinks.selectedIndex];

  window.location.href=szNewURL;

}

Вначале мы определяем номер выбранного элемента как значение Sel.ListOfLinks.selectedIndex. Затем это значение используется как индекс в массиве document.links, из которого в цикле происходило заполнение нашего списка.



Доступ к полям аплета Java из сценария JavaScript


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

Заметим, что сценарию JavaScript доступны только те поля и методы аплета, определенные как public.

На рис. 6.2 показан внешний вид документа HTML, в котором расположен один аплет и форма с одним многострочным текстовым полем и одной кнопкой.

Рис. 6.2. Сценарий JavaScript вызывает получает информацию от аплета

В окне аплета, расположенном в верхней части документа, находится поле редактирования текста и кнопка с надписью “Получить строку”. Если набрать в поле редактирования любую текстовую строку и нажать эту кнопку, то введенная строка будет отображена в нижней части аплета после символа >. Такой аплет мы описали в 30 томе “Библиотеки системного программиста” в разделе “Приложение TxtField” пятой главы.

Если нажать кнопку “Get applet info and text”, то сценарий JavaScript извлечет из аплета введенную текстовую строку (она хранится в поле с именем str), а также получит описание аплета, вызвав метод getAppletInfo, определенный в нашем аплете.

Введенная строка и информация об аплете будет затем отображена сценарием в многострочном поле редактирования, как это показано на рис.6.2.

Таким образом, наш сценарий обращается к полю и методу, определенным в аплете.

Исходный текст документа HTML вы найдете в листинге 6.3.

Листинг 6.3. Файл chapter6/TxtField/TxtField.html

<HTML>

  <HEAD>

    <TITLE>Get text</TITLE>

    <SCRIPT LANGUAGE="JavaScript">

    <!--

    function getTextFromApplet()

    {

      var szMsg="null";

      GetForm.Comment.value = document.applets[0].str +

      "\n" + "---------------------------\n" +

      document.applets[0].getAppletInfo();

    }

    // -->

    </SCRIPT>

  </HEAD>

  <BODY>

    <HR>

    <APPLET

      CODE=TxtField.class


      NAME="TxtField"

      ID=TxtField

      WIDTH=320

      HEIGHT=140>

    </APPLET>

    <HR>

    <FORM NAME="GetForm">

      <P><TEXTAREA NAME="Comment"

        ROWS="7" COLS="45">

      </TEXTAREA>

      <P>

      <INPUT TYPE="button" VALUE=" Get applet info and text" onClick="getTextFromApplet();">

    </FORM>

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

  </BODY>

</HTML>

Для кнопки, расположенной в форме с именем GetForm, мы определили обработчик события onClick:

onClick="getTextFromApplet();"

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

Функция getTextFromApplet обращается к аплету как к самому первому элементу массива document.applets[0]:

GetForm.Comment.value = document.applets[0].str +

  "\n" + "---------------------------\n" +

  document.applets[0].getAppletInfo();

Здесь мы записываем в свойство value многострочного поля GetForm.Comment значение переменной str, к которому добавлен разделитель из символов “-“ и строка описания аплета, полученная от метода getAppletInfo.

Исходный текст аплета приведен в листинге 6.4.

Листинг 6.4. Файл chapter6/TxtField/TxtField.java

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

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

//

// (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.*;

public class TxtField extends Applet

{

  // Создаем ссылку на объекты типа TextField

  TextField txt;

  // Создаем ссылку на объекты типа Button

  Button btnGetText;

  // Строка для хранения введенных данных

  public String str;



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

  // getAppletInfo

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

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

  public String getAppletInfo()

  {

    return "Name: TxtField\r\n" +

      "Author: Alexandr Frolov\r\n" +

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

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

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

  }

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

  // init

  // Метод, получающий управление при инициализации аплета

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

  public void init()

  {

    // Создаем редактируемое однострочное текстовое поле

    txt = new TextField("Введите строку текста", 35);

    // Создаем кнопку, с помощью которой можно получить

    // содержимое текстового поля

    btnGetText = new Button("Получить строку");

    // Добавляем текстовое поле в окно аплете

    add(txt);

   

    // Добавляем кнопку в окно аплете

    add(btnGetText);

    // Получаем и сохраняем текущий текст,

    // установленный в поле

    str = txt.getText();

    // Устанавливаем цвет фона

    setBackground(Color.yellow);

  }

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

  // action

  // Метод вызывается, когда пользователь выполняет

  // действие над компонентами

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

  public boolean action(Event evt, Object obj)

  {

    // Ссылка на кнопку, от которой пришло сообщение

    Button btn;

    // Проверяем, что событие вызвано кнопкой, а не

    // другим компонентом

    if(evt.target instanceof Button)

    {

      // Получам ссылку на кнопку, вызвавшую событие

      btn = (Button)evt.target;

      // Проверяем ссылку на кнопку

      if(evt.target.equals(btnGetText))



      {

        // Получаем и сохраняем текущий текст,

        // установленный в поле

        str = txt.getText();

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

        repaint();

      }

      // Если событие возникло от неизвестной кнопки,

      // мы его не обрабатываем

      else

      {

        return false;

      }

      // Возвращаем признак того, что мы обработали событие

      return true;

    }

    // Если событие вызвано не кнопкой,

    // мы его не обрабатываем

    return false;

  }

     

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

  // paint

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

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

  public void paint(Graphics g)

  {

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

    Dimension dimAppWndDimension = size();

   

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

    g.setColor(Color.black);

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

    g.drawRect(0, 0,

      dimAppWndDimension.width  - 1,

      dimAppWndDimension.height - 1);

    // Рисуем строку, полученную из текстового поля

    g.drawString("> " + str, 10, 100);

  }

}

Этот текст воспроизведен нами с небольшими изменениями из 30 тома “Библиотеки системного программиста”. Изменения заключаются в том, что мы добавили к определению поля str ключевое слово public:

public String str;

Это необходимо для того чтобы поле str было доступно из сценария JavaScript.


E


Это свойство представляет собой константу e. Приблизительное значение этой константы равно 2,72.

Вот пример использования свойства E:

var nE;

nE = Math.E;

Здесь мы записываем в переменную nE значение константы e.



Exp


Экспоненциальная функция, значение которой равно числу e, возведенному в степень аргумента функции.

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

var nValueExp;

nValueExp = Math.exp(nValue);



Файл описания фреймов


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

Особенность такого документа - отсутствие на своем обычном месте области тела документа, выделенного операторами <BODY> и </BODY>. Вместо этого в файле описания фреймов располагаются операторы <FRAMESET>, </FRAMESET>, <NOFRAME> и </NOFRAME>, как это показано ниже:

<HTML>

  <HEAD>

    . . .

  </HEAD>

  <FRAMESET

     ROWS="Высота_строки"

     COLS="Ширина_колонки"

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

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

     <FRAME SRC="Адрес_URL" NAME="Имя_фрейма">

       . . .

     <FRAME SRC="Адрес_URL" NAME="Имя_фрейма">

     <NOFRAME>

       <BODY>

         . . .

       </BODY>

     </NOFRAME>

  </FRAMESET>

</HTML>

Параметры ROWS и COLS оператора <FRAMESET> определяют размеры фреймов и задаются в виде списка значений, разделенных запятой.

Вы можете определить обработчики событий onLoad и onUnload, получающие управление, соответственно, при загрузке содержимого в главное окно фрейма и при замене текущего документа HTML в этом окне на другой. Фактически эти обработчики относятся не к фреймам, а к окну, где эти фреймы отображаются.

Для тех браузеров, которые не могут работать с фреймами, необходимо подготовить документ HTML, расположив его тело между операторами <NOFRAME> и </NOFRAME>. В этом документе имеет смысл разместить сообщение о том, что для просмотра данной страницы Web необходимо применять более современный браузер.



Фиксация повторных посещений страницы


В нашем первом примере документ HTML содержит форму с двумя кнопками (рис. 7.1).

Рис. 7.1. Кнопки для перехода к динамически создаваемому документу HTML и для удаления cookie

Если нажать на кнопку Go to page, сценарий JavaScript создаст новый документ HTML. Внешний вид этого документа зависит от того, сколько раз пользователь нажимал на эту кнопку.

Кнопка Remove All Cookies предназначена для удаления cookie, созданного в нашем документе HTML.

Когда вы нажимаете на кнопку Go to page в первый раз, cookie еще не создано. При этом создается документ HTML, внешний вид которого показан на рис. 7.2.

Рис. 7.2. Внешний вид созданного динамически документа HTML при первом посещении

Во второй и последующий разы внешний вид документа изменяется (рис.7.3).

Рис. 7.3. Внешний вид созданного динамически документа HTML при третьем посещении

Теперь здесь виден новый заголовок, а также содержимое параметров cookie с именами Visit и Count.

При каждом новом посещении значение параметра Count будет увеличиваться на единицу. Если же в документе, показанном на рис. 7.1, нажать кнопку Remove All Cookies, подсчет посещений начнется заново.

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

Листинг 7.1. Файл chapter7/Again/Again.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 + "=" + szValue + "; expires=" +

        dtExpiryDate;

    }

    function findCookie(szName)

    {

      var i = 0;

      var nStartPosition = 0;

      var nEndPosition = 0; 

      var szCookieString = document.cookie; 

      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;

          return document.cookie.substring( nStartPosition,nEndPosition); 

          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()

    {

      if(findCookie("Visit") == "")

      {

        addCookie("Visit","Alexandr_Frolov",10);

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

        document.write("<H2>You are welcome!</H2>");     

      }

      else

      {

        var szCnt = findCookie("Count");

        var i=0;

        if(szCnt != "")

        {

          i = szCnt;

          i++;

          szCnt = i.toString();

 

          addCookie("Count",szCnt,10);

        }

        document.write("<H2> You are welcome AGAIN!</H2>");    

        document.write(document.cookie);    

      }

    }

    // -->

    </SCRIPT>

  </HEAD>

  <BODY BGCOLOR=white>

    <H1>Visit our page!</H1>

    <FORM NAME="TestForm">

      <P><INPUT TYPE="button" VALUE="Go to page"

      onClick="btnClick();">

      <P><INPUT TYPE="button" VALUE="Remove All Cookies"



      onClick="removeCookie('Count');removeCookie('Visit')">

    </FORM>   

  </BODY>

</HTML>

Функции addCookie, findCookie и removeCookie, определенные в этом документе, вам уже знакомы. Они предназначены, соответственно, для создания cookie, извлечения значения заданного параметра cookie и удаления cookie.

Функция btnClick вызывается, когда пользователь нажимает в форме кнопку с надписью Go to page.

Прежде всего эта функция ищет параметр cookie с именем Visit. Если такой параметр не найден, считается, что страница посещается в первый раз. В этом случае функция btnClick создает параметры cookie с именами Visit и Count, а затем формирует текст документа HTML с приглашением:

addCookie("Visit","Alexandr_Frolov",10);

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

document.write("<H2>You are welcome!</H2>");

В том случае, когда пользователь посещает страницу повторно, параметр cookie с именем Visit уже существует. В этом случае функция btnClick пытается найти параметр с именем Count и получить его значение:

var szCnt = findCookie("Count");

Это значение затем увеличивается на единицу и записывается обратно в параметр cookie с именем Count:

i = szCnt;

i++;

szCnt = i.toString();

addCookie("Count",szCnt,10);

Завершая свою работу, функция btnClick записывает приглашение для повторно посетивших страницу пользователей и отображает содержимое свойства document.cookie:

document.write("<H2>You are welcome AGAIN!</H2>");    

document.write(document.cookie);    

Обработчик события onClick кнопки с надписью Remove All Cookies вызывает функцию removeCookie для параметров cookie с именами Count и Visit, удаляя их:

<INPUT TYPE="button" VALUE="Remove All Cookies"

onClick="removeCookie('Count');removeCookie('Visit')">


Floor


Вычисление наибольшего целого значения, меньшего или равного аргументу функции.

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

var nValue;

nValue = Math.floor(nArg);



Форма и ее свойства


Подробно о том, как создавать формы в документах HTML, мы рассказывали в 29 томе “Библиотеки системного программиста”. Сейчас мы повторим основные моменты, сделав акцент на вопросах, важных для обработки форм средствами сценариев JavaScript.



Функции в языке сценариев JavaScript


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

Обычно функции определяются в разделе заголовка документа HTML, отмеченного операторами <HEAD> и </HEAD>. Как мы уже говорили, функция должна быть определена перед вызовом. Размещение всех определений функций в разделе заголовка документа HTML гарантирует доступность этих функций при обработке документа.

Общий вид определения функции представлен ниже:

function имя([параметр 1] [,параметр 2] [...,параметр N])

{

  . . .

  строки тела функции

  . . .

  [return значение]

}

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

С помощью ключевого слова return функция может вернуть значение.



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


Определение даты, хранящейся в объекте класса Date.

Метод возвращает значение календарной даты в диапазоне от 1 до 31.

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

var dtNewDate;

var nDate;

dtNewDate = new Date();

nDate = dtNewDate.getDate();



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


Определение номера дня недели, хранящегося в объекте класса Date.

Метод возвращает 0 для воскресения, 1 - для понедельника, и так далее.

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

nDay = dtDate.getDay();



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


Определение количества часов, прошедших после полуночи.

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

nHours = dtDate.getHours();



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


Определение количества минут, прошедших после начала часа.

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

nMinutes = dtDate.getMinutes();



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


Определение количества месяцев, прошедших с января.

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

nMonth = dtDate.getMonth();



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


Определение количества секунд, прошедших с начала минуты.

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

nSeconds = dtDate.getSeconds();



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


Определение времени для заданного объекта класса Date.

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

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

nMilliseconds = dtDate.getTime();



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


Определение смещения локального времени относительно времени по Гринвичу (в миллисекундах).

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

nOffsetMilliseconds = dtDate.getTimeZoneOffset();



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


Метод getYear возвращает год, хранящийся в объекте класса Date.

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

nYear = dtDate.getYear();



Иерархия объектов браузера


Иерархия объектов браузера схематически показана на рис. 2.2.

Рис. 2.2. Иерархия объектов браузера

Объект window находится в корне иерархии. Когда в окно браузера загружается документ HTML, внутри этого объекта создаются другие объекты - document, parent, frame, location и top.

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

Объект document содержит в себе другие объекты, состав которых полностью определяется документом HTML, загруженным в окно браузера. Это могут быть формы, ссылки на другие документы HTML или локальные ссылки внутри одного документа, объекты, определяющие адрес URL документа и так далее.

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

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



Иерархия объектов в формах


Как мы уже говорили, при загрузке документа HTML в окно браузера Internet создается объект класса Document. Если в этом документе определены формы, то они доступны сценариям JavaScript как свойства объекта Document.

В разделе “Ссылки и метки в документе” предыдущей главы мы определили форму, задав для нее имя Sel с помощью параметра NAME оператора <FORM>:

<FORM NAME="Sel">

  <SELECT NAME="ListOfLinks">

  </SELECT>

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

</FORM>

В результате у объекта Document появилось свойство Sel. К этому свойству можно адресоваться следующим образом:

Document.Sel

Любая форма содержит определения полей и органов управления, таких как списки, переключатели и кнопки. При определении полей и органов управления им можно задать имя, указав его в параметре NAME соответствующего оператора языка HTML. В примере, приведенном выше, в форме определен список с именем ListOfLinks.

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

Document.Sel.ListOfLinks

Так как поля формы и органы управления являются объектами, то для них определены свои свойства и методы. Например, свойство selectedIndex, содержащее номер выбранного пользователем элемента списка, доступно следующим образом:

Document.Sel.ListOfLinks.selectedIndex

С помощью рис. 2.2 вы можете проследить иерархию объектов документа и, в частности, иерархию объектов в формах.

Заметим, что в качестве одного из свойств объекта Document определено свойство forms. Это массив всех форм, расположенных в документе HTML. Размер массива равен document.forms.length.

Вы можете адресоваться к формам как к элементам массива forms, причем первый элемент массива (с индексом 0) соответствует самой первой форме, определенной в документе, второй - следующей и так далее. Однако удобнее обращаться к формам по их именам, заданным в параметре NAME оператора <FORMS>.



Использование команды вызова отладчика


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

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

Листинг 8.1. Файл chapter8/callDebugger.html

<HTML>

  <HEAD>

    <TITLE>Hello, world!</TITLE>

    <SCRIPT LANGUAGE="JavaScript">

    <!--

    var szHelloMsg = "Hello, world!";

    function printString(szString)

    {

      document.write(szString.bold());

    }

    function printHello()

    {

      debugger;

      printString(szHelloMsg);

    }

    // -->

    </SCRIPT>

  </HEAD>

  <BODY BGCOLOR=white>

    <H1>JavaScript Test</H1>

    <P>Message:

    <SCRIPT LANGUAGE="JavaScript">

    <!--

    printHello();

    // -->

    </SCRIPT>  </BODY>

</HTML>

Обратите внимание, что в функции printHello мы вставили строку вызова отладчика непосредственно перед обращением к функции printString.

Когда вы попробуете просмотреть этот документ в браузере Microsoft Internet Explorer версии 4.0 с установленным отладчиком Microsoft Script Debugger, на экране появится окно отладчика, показанное на рис. 8.2.

Рис. 8.2. Окно отладчика Microsoft Script Debugger

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



Изменение внешнего вида графических ссылок


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

Рис. 5.1. Кнопка с надписью АУРАМЕДИА изменила свой цвет

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

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

Листинг 5.1. Файл chapter5/grbutton/grbutton.html

<HTML>

  <BODY BGCOLOR="#B0FFD8">

  <FONT FACE="Arial, Helvetica" SIZE=1>

  <P>

  <A HREF="mainaur.htm"

    onMouseOver="document.btn1.src='pic/aurap.gif'"

    onMouseOut="document.btn1.src='pic/aura.gif'"><IMG

    SRC="pic/aura.gif" NAME = "btn1" BORDER=0 ALT="Журнал Аурамедиа"</A>

  <BR>

  <A HREF="soft/default.htm"

    onMouseOver="document.btn2.src='pic/softcatp.gif'"

    onMouseOut="document.btn2.src='pic/softcat.gif'"><IMG

    SRC="pic/softcat.gif" NAME = "btn2" BORDER=0 ALT="Soft-каталог"</A>

  </LEFT>

  </FONT>

  </BODY>

</HTML>

Для создания ссылок мы воспользовались оператором <A>. Этот оператор использован здесь совместно с оператором <IMG>, поэтому ссылка отображается как графическое изображение.

Для оператора ссылки <A> мы определили обработчики событий onMouseOver и onMouseOut:

onMouseOver="document.btn1.src='pic/aurap.gif'"

onMouseOut="document.btn1.src='pic/aura.gif'"

Когда курсор мыши оказывается над ссылкой (то есть над графическим изображением ссылки), управление получает обработчик события onMouseOver. Этот обработчик загружает изображение pic/aurap.gif, где слово АУРАМЕДИА написано красным цветом (для второй кнопки в аналогичной ситуации загружается изображение pic/softcatp.gif).

После того как пользователь убирает курсор мыши с поверхности кнопки, в дело включается обработчик события onMouseOut. Он восстанавливает исходное изображение, указанное в параметре SRC оператора <IMG>.



Изменение значений переменных


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

Чтобы изменить значение переменной или свойства объекта, допускающего изменение значения, вы можете воспользоваться обычным оператором присвоения. На рис. 8.8 мы показали, как можно вначале просмотреть значение переменной szHelloMsg, а затем изменить его.

Рис. 8.8. Изменение значения переменной szHelloMsg

Если теперь продолжить выполнение сценария, на экране вместо строки Hello, world! появится новое сообщение (рис. 8.9).

Рис. 8.9. Сообщение изменилось после изменения значения переменной szHelloMsg



Изменение значения параметра cookie


Для изменения значения параметра cookie с заданным именем вы можете просто вызвать функцию addCookie еще раз:

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

// Значение параметра Count равно 0

  . . .

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

// Значение параметра Count равно 5

Здесь мы вначале установили для параметра Count значение 0, а затем изменили это значение на 5.



Электронные часы


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

Рис. 3.20. Электронные часы в документе HTML

Исходный текст документа HTML с электронными часами представлен в листинге 3.10.

Листинг 3.10. Файл chapter3/clock/clock.html

<HTML>

  <HEAD>

    <TITLE>Электронные часы</TITLE>

    <SCRIPT LANGUAGE="JavaScript">

    <!--

    nTimer = 0;

    var szCurrentTime = "";

    var szCurrentDate = "";

    var szTimeZone = "";

    var szGMT = "";

    var szLocal = "";

    function updateClock()

    {

      var dtDate   = new Date();       

      var nHours   = dtDate.getHours();

      var nMinutes = dtDate.getMinutes();       

      var nSeconds = dtDate.getSeconds();

      szCurrentTime = nHours + ":" + nMinutes +

        ":" + nSeconds;

  

      szCurrentDate = dtDate.getDate() + "." +

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

      szTimeZone = dtDate.getTimezoneOffset() / 60;

      szGMT = dtDate.toGMTString();

      szLocal = dtDate.toLocaleString();

      Clock.time.value = szCurrentTime;

      Clock.dat.value  = szCurrentDate;

      Clock.timeZone.value = szTimeZone;

      Clock.gmt.value  = szGMT;

      Clock.loc.value  = szLocal;

      nTimer = setTimeout("updateClock()", 1000);

    }

    // -->

    </SCRIPT>

  </HEAD>

  <BODY BGCOLOR=white>

    <H1>Электронные часы</H1>

    <FORM NAME="Clock">

      <TABLE>

       <TR><TD><B>Дата:</B></TD><TD><INPUT TYPE="text"

         NAME="dat" SIZE="20" ></TD>

       </TR>


       <TR><TD><B>Время:</B></TD><TD><INPUT TYPE="text"

         NAME="time" SIZE="20" ></TD>

       </TR>

       <TR><TD><B>Смещение часового пояса:</B></TD><TD><INPUT TYPE="text"

         NAME="timeZone" SIZE="20" ></TD>

       </TR>

       <TR><TD><B>Дата GMT:</B></TD><TD><INPUT TYPE="text"

         NAME="gmt" SIZE="30" ></TD>

       </TR>

       <TR><TD><B>Локальная дата:</B></TD><TD><INPUT TYPE="text"

         NAME="loc" SIZE="30" ></TD>

       </TR>

      </TABLE>

    </FORM>

    <SCRIPT LANGUAGE="JavaScript">

    <!--

      updateClock();

    // -->

    </SCRIPT>

  </BODY>

</HTML>

Часы запускаются сразу после загрузки документа HTML в окно браузера. При этом управление получает функция updateClock. Эта функция определена в заголовке, а ее вызов находится в конце области тела документа HTML.

Получив управление, функция updateClock создает объект Data для текущей даты, установленной в компьютере:

var dtDate   = new Date();       

Затем функция определяет три компоненты времени (часы, минуты и секунды), вызывая для этого методы getHours, getMinutes и getSeconds, определенные в классе Date:

var nHours   = dtDate.getHours();

var nMinutes = dtDate.getMinutes();       

var nSeconds = dtDate.getSeconds();

Полученные таким образом значения комбинируются в текстовой строке szCurrentTime:

szCurrentTime = nHours + ":" + nMinutes +

        ":" + nSeconds;

В дальнейшем время будет записано функцией updateClock в поле time формы Clock, как это показано ниже:

Clock.time.value = szCurrentTime;

Строка текущей даты получается в результате вызова методов getDate, getMonth и getYear:



szCurrentDate = dtDate.getDate() + "." +

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

Эта строка записывается в поле dat формы Clock:

Clock.dat.value  = szCurrentDate;

Для вычисления смещения часового пояса мы воспользовались методом getTimezoneOffset, возвращающим значение в минутах:

szTimeZone = dtDate.getTimezoneOffset() / 60;

Для того чтобы вычислить смещение в часах, мы разделили результат, полученный от метода getTimezoneOffset, на 60.

Вычисленное смещение часового пояса записывается в поле timeZone формы Clock:

Clock.timeZone.value = szTimeZone;

Для получения времени по Гринвичу мы воспользовались методом toGMTString:

szGMT = dtDate.toGMTString();

Полученное значение будет записано в поле gmt формы Clock:

Clock.gmt.value  = szGMT;

И, наконец, локальную дату и время мы определяем с помощью метода toLocaleString:

szLocal = dtDate.toLocaleString();

Результат записывается в поле loc формы Clock:

Clock.loc.value  = szLocal;

Периодическое выполнение функции updateClock достигается с помощью метода setTimeout:

nTimer = setTimeout("updateClock()", 1000);

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


Как связаться с авторами


Полную информацию о всех наших книгах серий “Библиотека системного программиста” и “Персональный компьютер. Шаг за шагом”, а также дискеты к книгам, статьи и другую информацию вы можете найти в сети Internet на серверах Web по следующим адресам:

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

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

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

frolov@glas.apc.org

frolov.alexandr@usa.net

Если электронная почта вам недоступна, присылайте ваши отзывы в АО “Диалог-МИФИ” по адресу:

115409, Москва, ул. Москворечье, 31, корп. 2,

тел. 324-43-77

Приносим свои извинения за то что не можем ответить на каждое письмо. Мы также не занимаемся продажей и рассылкой книг, дискет, компакт-дисков, рекламы, отдельных фрагментов наших книг и исходных текстов к книгам. По этим вопросам обращайтесь непосредственно в издательство “Диалог-МИФИ”. Авторский комопакт-диск можно приобрести также в издательстве “Аурамедиа”.



Как закрыть окно браузера


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

Рис. 2.4. Документ HTML, способный закрыть главное окно браузера

Если нажать на кнопку с названием “Close Navigator Window”, сценарий отобразит на экране диалоговую панель, показанную на рис. 2.5.

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

Данная диалоговая панель отображается с помощью метода confirm. Если вы нажмете на кнопку OK, сценарий попытается закрыть окно браузера при помощи метода close.

Заметим, что браузер Microsoft Internet Explorer версии 4.0 запрашивает разрешение на закрытие окна еще раз (рис. 2.6).

Рис. 2.6. Второй вопрос о закрытии главного окна браузера

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

Листинг 2.3. Файл chapter2/CloseAll/CloseAll.html

<HTML>

  <HEAD>

    <TITLE>Закрываем окно браузера</TITLE>

    <SCRIPT LANGUAGE="JavaScript">

    <!--

    function CloseNavWnd()

    {

      if(confirm("Вы действительно желаете закрыть окно браузера?"))

        window.close();

    }

    // -->

    </SCRIPT>

  </HEAD>

  <BODY BGCOLOR=white>

    <H1>Закрываем окно браузера</H1>

    <P>Для того чтобы закрыть окно браузера,

нажмите кнопку &quot;Close Navigator Window&quot;,

расположенную ниже:

    <FORM NAME="selectForm">

      <P><INPUT TYPE="button" VALUE="Close Navigator Window"

      onClick="CloseNavWnd();">

    </FORM>   

  </BODY>

</HTML>

В области заголовка документа определена функция CloseNavWnd:

function CloseNavWnd()

{

  if(confirm("Вы действительно желаете закрыть окно браузера?"))

    window.close();

}

Эта функция обращается к методу confirm, который выводит на экран диалоговую панель с запросом на закрытие окна. Если пользователь нажмет кнопку OK, метод возвратит значение true, а если на кнопку Cancel - значение false.

В случае положительного ответа функция CloseNavWnd вызывает метод close для текущего объекта window. В данном случае таким объектом является окно браузера. Заметим, что вместо объекта window можно указывать объект self, так как это синоним текущего окна:

self.close();

Для того чтобы функция CloseNavWnd вызывалась после того как пользователь нажимает кнопку, в строке определения этой кнопки мы указали обработчик события onClick:

<P><INPUT TYPE="button" VALUE="Close Navigator Window"

  onClick="CloseNavWnd();">

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



Кнопка button


В общем виде кнопка класса button определяется в форме с помощью оператора <INPUT> следующим образом:

<INPUT TYPE="button"

  NAME="Имя_кнопки"

  VALUE="Надпись_на_кнопке"

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

Параметр TYPE оператора <INPUT> должен иметь значение button, как это показано в нашем примере.

С помощью параметра NAME задается имя объекта, соответствующего кнопке (а не надпись на кнопке). Надпись на кнопке указывается с помощью параметра VALUE.

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



Конструкторы класса Date


Для использования большинства методов класса Date необходимо создать объект этого класса при помощи одного из трех конструкторов.

Конструктор первого вида вызывается следующим образом:

var dtNewDate;

dtNewDate = new Date();

Здесь создается объект Date, в котором хранится информация о текущей дате и времени. Это время задается по Гринвичу или, пользуясь более современным определением, с использованием времени Universal Coordinated Time.

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

var dtNewDate;

dtNewDate = new Date(nMilliseconds);

Параметр nMilliseconds задает дату в миллисекундах, считая от 1 января 1970 года.

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

var dtNewDate;

dtNewDate=new Date(year, month, date, hours, min, sec, ms);

Параметры этого конструктора описаны ниже:

Параметр

Описание

year

Год, например, 1998 или 2012

month

Номер месяца от 0 (январь) до 11 (декабрь)

date

Календарная дата, задается в диапазоне от 1 до 31

hours

Необязательный параметр, задающий час дня в диапазоне от 0 до 23. Вы обязаны указывать этот параметр только в том случае, если задан параметр min

min

Необязательный параметр, задающий минуты в диапазоне от 0 до 59. Вы обязаны указывать этот параметр только в том случае, если задан параметр sec

sec

Необязательный параметр, задающий секунды в диапазоне от 0 до 59. Вы обязаны указывать этот параметр только в том случае, если задан параметр ms

ms

Необязательный параметр, задающий миллисекунды в диапазоне от 0 до 999