Веб-дизайн - Учебники - Сайтостроительсво и веб-дизайн - Глава 18 JavaScript и пользовательский ввод

Глава 18. JavaScript и пользовательский ввод

События Java Script
Типы обработчиков ошибок
Указатель this
Объектная модель документа
Область действия и указатели
Работа с объектами верхних уровней
Java Script и формы HTML
Объекты form
Обработка ошибок на форме с помощью Java Script
Java Script на клиентской машине
Переадресация, фреймы и Java Script
Переадресация браузера
Как написать меню ссылок на Java Script
Java Script и фреймы
Резюме
В этой главе мы обсудим круг задач, решаемых с помощью JavaScript. Вы узнаете о различных способах обработки событий, происходящих на веб-странице с участием пользователей.

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

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

В этой главе вы найдете следующие разделы:

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

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

Все, что пользователь может делать на странице, называется событием, как и все, что автоматически происходит на странице или в браузере (или в системе). Например, загрузка страницы — событие.

Выгрузка страницы — это, разумеется, тоже событие.

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

В общем случае формат следующий:

<element обработчик="код JavaScript или вызов функции"> </element>
Существует определенный набор элементов HTML, которые имеют поддержку атрибутов, связанных с обработчиками событий. Есть, например, обработчики, специально предназначенные для работы с элементом <body> и позволяющие определять какие-то автоматические действия при загрузке страницы в браузере.

Элементы <form> имеют множество обработчиков событий.

Мы рассмотрим пример, который позволяет по нажатию кнопки подтверждать не форму целиком, а только данные, передаваемые в функцию JavaScript:

<Н1>ОбраОотка введенных данных</H1><form> Введите число: <input type="text" name="userEntry" size="4" /> <br />Результат обработки: <input <type="text" name="result" size="5" /> <br /><input type="button" уа!ие="Счет" onclick="result.value = compute(userEntry)" /></form>
Что делает этот отрывок кода? Просит пользователя ввести число в поле, расположенное в начале формы. После этого ему нужно нажать кнопку «Счет». При этом будет запущен обработчик события onclick. В нем происходит вызов некоторой функции под названием compute. Ей передается указатель на значение, каковым является объект <input> по имени userEntry. Из него функция извлечет данные, обработает их и возвратит результат, присвоив его переменной result. Эта переменная выводится в текстовом поле на форме. Именно для этого второе текстовое поле имеет то же значение атрибута name, что и переменная, хранящая нужную информацию. В браузере при загрузке такой страницы вы увидите то, что представлено на рис. 18.1. (Обратите внимание на то, что сама функция в примере не показана, но все, что она делает, — это добавляет к исходному значению число 100.)

 

Рис. 18.1. Используя обработчики ошибок и элементы формы, JavaScript может возвращать значения, не заботясь о CGI-скриптах

Типы обработчиков ошибок

События, относящиеся в значительной степени к формам, представляющие собой атрибуты скриптов, у которых в то же время отсутствуют формальные требования элемента <script>, называются внутренними. Тем не менее они могут работать не только с элементами <form>. Некоторые события бывают связаны с какими-то определенными элементами HTML, а другие — с целым рядом элементов. И те и другие представлены в табл. 18.1.

Таблица 18.1. Обработчики событий

Обработчик  Событие
onfocus  Заполнение (получение фокуса) элемента формы (ввод данных, нажатие
при помощи клавиатуры или мыши). Элементы <input>, <select>, <textarea>
и <button>, а также некоторые другие: <а>, <label>
onblur  «Выход» из элементов (потеря фокуса), перечисленных в предыдущем
описании событий, с помощью мыши или клавиатуры
onclick  Пользователь щелкает на элементе
ondbclick  Двойной щелчок
onchange  Изменение значения и выход из элемента формы (только для <input>,
<select> и <textarea>)
onkeypressed  Нажатие клавиши, когда элемент в фокусе (то есть выбран)
onkeydown  Удерживание клавиши, когда элемент в фокусе
onkeyup  Отпускание клавиши, когда элемент в фокусе
onload  Загрузка страницы (используется только с <body> и <frameset>)
onunload  Выгрузка страницы (используется только с <body> и <frameset>)
onmouseover  Наведение указателя мыши на элемент
onmousedown  Нажатие кнопки мыши, когда ее указатель находится на элементе
onmouseup  Отпускание кнопки мыши, когда ее указатель находится на элементе
onmousemove  Перемещение мыши, когда ее указатель находится на элементе
onmouseout  Перемещение мыши, связанное с уходом с элемента
onselect Выбор поля <input> или <textarea>
onreset  Очистка формы (используется только с элементом <form>)
onsubmit  Подтверждение формы (используется только с элементом <form>)

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

<body onunload="alert('Спасибо за визит! Приходите еще!')">
В этом примере показано, что в JavaScript можно использовать как одинарные, так и двойные кавычки. Думаю, понятно, почему и зачем. Если в приведенном примере везде использовать одинаковые кавычки, то "al ert" закроется слишком быстро.

Итак, одним из способов отреагировать на пользовательский ввод является показ какого-нибудь сообщения. Сообщение типа alert похоже на диалоговое окно, разница состоит только в том, что вместо двух кнопок на нем расположена одна. Это называется «окном предупредительных сообщений». Так вот, это окно являетсяпримером прямого взаимодействия с пользователем, причем часто главное окно браузера блокируется до тех пор, пока оно не будет закрыто.

СОВЕТ

Если хотите, чтобы в окне сообщений было больше одной строки, используйте спецсимвол перевода каретки (\n).

Помимо встроенных функций типа alert() можно, разумеется, вызывать и собственные:

 <input type="text" name="phoneNumber" onchange="checkPhone (this.value)" />
В этом примере вызывается функция checkPhone(), ей передается значение, хранящееся в поле ввода <input>.c именем phoneNumber. Как именно передается? Вопрос хороший, поскольку на самом деле передается не само значение, а указатель на него. Причем не простой, а служебный указатель this, речь о котором пойдет далее.

Указатель this

По сути дела, указатель this заменяет имя текущего объекта. В данном случае того объекта, с которым связан обработчик. Рассмотрим пример, являющийся продолжением предыдущего:

<form name="myForm"><input type="text" name="phoneNumber"onchange="checkPhone (this.value)" /></form>
Здесь буквально говорится с помощью this: «Этот элемент ввода (input)», value является свойством, хранящим значение, ассоциированное с данным i nput, то есть то, что ввел пользователь. Можно получить доступ к этому значению (с целью его передачи) и по-другому:

<form name="myForm"><input type="text" name="phoneNumber" onchange="checkPhone(document.myForm.phoneNumber.value)" /></form>
Вот чтобы не запутываться в этом длинном «пути» (document.myForm.phoneNumber), и используется указатель this.

Объектная модель документа

Ключевое слово this является скрытым предвестником целой концепции, которую нужно изучить, прежде чем продолжить разговор об обработке форм. Эта концепция сокращенно называется DOM (Document Object Model) и является своеобразным расширением и продолжением объектно-ориентированного подхода, речь о котором мы вели еще в главе 17. Она касается документов, которые создаются на XHTML и с которыми приходится работать при написании программ на JavaScript.

По определению DOM является стандартом консорциума W3C, определяющим приемы управления объектами и изображениями на одной веб-странице.

Вы только что рассмотрели пример работы этой модели. В самом последнем примере в качестве обработчика событий элемента <i nput> указывалось следующее:

onchange="checkPhone (document.myForm.phoneNumber.value)"
Вся ссылка, начинающаяся со слова document, — это ссылка на объектную модель документа. Она начинается с самого общего, что есть в этой модели, — слова document, затем «закапывается» в глубь элементов, имеющихся в составе веб-страницы. Самым общим элементом из нужных нам является форма — объект myForm, а уже внутри него находятся все остальные объекты. phoneNumber содержит набор свойств конкретного <input>; свойство value является одним из них и хранит введенное пользователем значение. Оно-то нам и нужно. Таким образом мы прошли от самого общего к частному и построили указатель на требуемое значение.

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

Листинг 18.1. Непосредственная работа с объектами веб-документа

<!DOCTYPE html PUBLIC "\//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtmll/DTD/xhtmll-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml "><head><title> Передача значений по ссылке </title><meta http-equiv="Content-Script-Type"content="text/javascript"><script><!-- прячем код скрипта от нерадивых браузеровfunction compute()var myNum = document.myForm.userEntry.value:myNum = eval(myNum):var myResult = myNum + 100:document.myForm.result.value = myResult:return:/ Закончили прятаться --> ,</script></head><body><h1>Обработка введенных данныx</hl><form name="myForm">Введите число: <input type="text" name="userEntry" size="4" /> <br />Результат обработки: <input type="text" name="result" size="5" /> <br /><input type="button" name="Calc" vаluе="Счет" onclick="compute()" l></form></body> </html>
Можете просто записать этот код в HTML-файл и убедиться в том, что все действительно работает. Каким же образом это происходит?

1. Пользователь вводит число в поле ввода userEntry.

2. При нажатии кнопки «Счет» запускается функция compute().

3. Функция находит по ссылке значение, введенное пользователем, и присваивает его переменной myNum. Затем с помощью встроенной функции eval () превращает myNum в число (поскольку поле текстовое и изначально переменная представляет собой просто набор символов, даже если это цифры).

4. Производятся какие-то арифметические операции, ответ сохраняется в переменной myResult.

5. Значение myResult присваивается свойству value текстового поля result, расположенного на второй строке формы. Ответ появляется в поле автоматически. (В браузере это выглядит точно так же, как на рис. 18.1.)

Существует один момент, за которым нужно следить при работе над такого рода скриптами. Он касается того, когда следует использовать свойство value, а когда нет. Обычно если вы хотите присвоить какое-то значение элементу формы, то вам оно просто необходимо. Потому что с поименованным элементом (например, userln-put) связано больше чем просто значение. У него есть, например, type, установленный в элементе <i nput>. Поэтому нельзя просто так взять и написать document. form, user Input = x, поскольку userlnput — это объект, а не свойство.

ПРИМЕЧАНИЕ

Стандарт DOM был принят консорциумом WWW совсем недавно, поэтому Internet Explorer, Netscape и другие браузеры несколько по-разному реализуют его. В тексте этой главы я буду стараться использовать только кросс-платформенные средства объектной модели документов (ну, по крайней мере те, которые работают и в IE, и в Netscape). Тем не менее в главе 19 будут обсуждаться различные платформозависимые элементы DHTML.

Область действия и указатели

Один из вопросов, традиционно вызывающих затруднения при использовании DOM, является написание полных путей к объектам. В общем случае нужно начинать, как уже говорилось, с самого общего, что может быть, и затем продвигаться до нужного элемента, не пропуская ничего. Уровни объектов отделяются при этом точками. Но на самом деле мы уже видели пример использования более короткого пути. Объектом самого высокого уровня обычно является окно, window. Поэтому, если бы мы честно использовали самый полный путь, нам следовало бы во всех предыдущих примерах начинать именно с него. Тогда указатели выглядели бы еще длиннее. Например: window. document. myForm. userEntry .value.

Но оказывается, что у всех этих путей есть некое общее свойство — они все имеют определенную область действия. Это означает, что, находясь на некотором виртуальном уровне объектов, можно часть пути отбросить, поскольку она в данном «месте» просто не актуальна. Это должно вам напомнить наш старый разговор о полных и сокращенных URL. Поскольку наши скрипты не влияют на окно браузера и мы находимся не на уровне «окон», а на уровне документов, то слово window в наших ссылках мы спокойно опускаем. Окно при этом считается текущим.

Вслед за вопросом областей действия возникает вопрос указателей. По определению, указатель — это переменная, содержащая адрес объекта. Указатели значительно упрощают систему доступа к различным переменным:

function computed() {var theForm = document.myForm;var Num = theForm.userEntry.value;Num = eval(Num);var Result = Num + 100;theForm.result.value = Result;return;}
Мы немного изменили листинг 18.1 и определили объект theForm для document .myForm во всех ссылках на объекты.

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

<form name="myForm">. . .другие элементы. . .«input type="button" name="Calc" value- ''Счет" onclick="compute(myForm)" /></form>
Обратите внимание, этот код немного отличается от представленного в листинге 18.1, поскольку в данном случае мы собираемся передавать в функцию имя текущей формы. Благодаря принципу областей действия, нам не нужно писать полный DOM-путь к объекту myForm. Дело в том, что мы уже в myForm и путь к любым свойствам в вызовах функции будет начинаться с этого имени объекта. Теперь можно переписать саму функцию, чтобы она понимала, какое значение ей передается, и создать указатель:

 function compute (theForm) { var Num = theForm.userEntry.value; Num = eval(Num):var Result = Num + 100: theForm.result.value = Result; return; }
Как видите, создать указатель достаточно просто. Нужно только разместить его имя в скобках после имени функции. При ее вызове будет автоматически создан реальный указатель, которому будет присвоен нужный путь в терминах объектной модели. И теперь, получая доступ к объектам и значениям с помощью указателя, можете работать с ним так, как будто вы написали не одно имя переменной-указателя, а полный путь.

Работа с объектами верхних уровней

Мы еще вернемся к объектам формы. А сейчас обратимся к некоторым объектам, входящим в DOM. В частности, поговорим о window, location и чуть более подробно о document.

Объект window

Даже если вы его не знаете, вы наверняка с ним знакомы. Ну, скажем так, встречали. Мы буквально в этой же главе упоминали функцию erl ert (). Полный путь к ней выглядит следующим образом: window, alert О. Это означает, что данный метод является принадлежностью объекта wi ndow. Однако до тех пор, пока вы не собираетесь вывести окно сообщения в каком-нибудь другом окне браузера, отличном от текущего, этот полный путь вам не нужен. Вы, вероятно, помните, что alent ( ) -выводит окно с сообщением, которое можно убрать, щелкнув на кнопке ОК. Пока окно активно, в главном окне браузера ничего не может происходить. Строка в скобках задает текст сообщения.

Как и у любого нормального объекта, у wi ndow есть свойства и методы. По большей части, свойства можно только считывать, а изменять нельзя, поскольку окно уже существует. Среди свойств есть такие как name (это то, что пишется в строке заголовка), 1 ength (число фреймов в окне), sel f (нечто типа указателя на самого себя, то есть на текущее окно) и status. Последнее можно использовать для изменения надписи в строке состояния браузера. Строка состояния обычно представляет собой краткое описание происходящего в данный момент на веб-странице. Вот пример:

<а href = "products.html" onmouseover = "status='Пocмотреть полную линейку продукции'" onmouseout="status=''">
Продукция </а>
У объекта window есть немало методов, позволяющих добавлять и изменять всякие рюшечки, касающиеся окна. Среди них есть уже знакомые alert( ) и eval ( ). Кстати говоря, eval () позволяет превращать любые строки в код JavaScript, а не только в числа.

При работе с window можно использовать такие методы, как, например, confirm( ), Делает он все то же самое, что и alert( ), только вместо одной кнопки ОК окно содержит две кнопки: ОК и Cancel (Отмена). Если пользователь щелкает на ОК, возвращается значение true, а если на крестике в верхнем правом углу или на кнопке Cancel, возвращается false. Например:

var keepGoing = confirm("Хотите продолжить?");
В то же семейство методов можно отнести prompt ( ), который тоже открывает диалоговое окошко, но при этом ожидает от пользователя ввода значения. Можно указать либо только текст сообщения, либо и текст сообщения, и подсказку, которая будет видна по умолчанию в поле ввода. Пример:

var numberGuess = prompt("Введите число". 5);var emailAddress = prompt("Введите e-mail", "vpupkin@fakecorp.com"):
Метод ореn( ) предназначен для открытия нового окна браузера. Можно указывать разные параметры, управляющие внешним видом окна, и даже задавать сразу URL, который будет открыт. Чтобы просто открыть окно и загрузить в него какую-нибудь веб-страницу, напишите выражение:

window.open("URL")
Существует такой метод: resizeTo( ). Он позволяет автоматически масштабировать окно браузера, то есть задать его высоту и ширину в пикселах. Например, если ваш сайт лучше всего смотрится при 800 х 600, можете включить в заглавную страницу следующую строку:

<body onload="window.resizeTo(800.600)">
Наряду со всеми этими свойствами и методами объект wi ndow имеет ряд подобъек-тов, среди которых location, document и history. О первых двух будет отдельный разговор, а что касается объекта history, то пару слов о нем я хочу сказать прямо сейчас. Его можно использовать в основном для получения доступа к URL, которые пользователь недавно открывал и которые браузер хранит в памяти. Среди свойств объекта history следующие: current, previous, next. Они служат для открытия недавно посещенных страниц. Свойство length позволяет узнать, сколько адресов хранит браузер. При этом метод history .go(x) позволяет перейти на страницу с номером х. Если х положительное, то метод будет отсчитывать страницы «назад». Если вы напишете отрицательное значение х, отсчет будет вестись «вперед». Вот еще два полезных метода hi story: back 0 и forward( ). Служат для перехода, соответственно, назад и вперед:

<а href="" onclick="history.back( )">Haзaд</a>
Объект location

Как уже говорилось, этот объект является частью объекта wi ndow, поэтому полный путь к нему следующий: window, location.

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

У этого объекта существует немало свойств,
и все они предназначены для получения определенных частей URL текущей страницы. Например, location.href возвращает весь URL:

 document.writeln("Aдрес этой страницы: " + location.href):
Все остальные свойства location возвращают какие-то отдельные части адреса. Рассмотрим полный список:

href. Полный URL.

protocol. Протокол (например, http:).

hostname. Имя хоста (например, www.fakecorp.com).
port. Номер порта, если это существенно.

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

Например, на каждой странице где-нибудь вуглу помещать ее реальный URL. Вспомним, как это делается:

document.writeln("Адрес этой страницы: " + location.href):
Можно, например, загрузить в браузер новую страницу таким способом:

 location.href = "http://www.fakecorp.com/newpage.html"
Объект document

Это еще одно детище объекта wi ndow. Однако деточка эта весьма взрослая и самостоятельная. На самом деле при написании скриптов на JavaScript и, в частности, при разработке форм именно document оказывается наиболее часто используемым объектом. Действительно, именно здесь хранятся все объекты и элементы ваших страниц.

И уровень document не низок, не высок, а как раз очень удобен.

Хочется упомянуть в первую очередь такие свойства данного объекта:

domain. Хранит имя домена, на котором расположен документ (например,
www.fakecorp.com).

url. URL текущего документа.

referrer. Может использоваться для хранения URL того документа, на котором стояла ссылка на данный (то есть адрес страницы, с которой пользователь сюда попал).

lastmodified. Дата внесения последних изменений.

title. Хранит заголовок документа (тот самый, который указан в элементе<title>)

anchors. Массив. В нем хранятся якоря документов с именами, связанными с ним.

images. Еще один массив. Этот хранит все изображения (вернее, ссылки на них).

forms. И еще массив. Позволяет получить доступ к разным формам страницы.
Почти все свойства говорят сами за себя. Что касается трех массивов anchors, images и forms, то доступ к ним осуществляется так же, как к массивам, которые обсуждались в главе 17. Например, чтобы отыскать URL первого изображения на странице, можно написать следующее:

alert(document.images[0].src);
А можно и изменить URL изображения, и это приведет к тому, что на странице появится ссылка на другой графический файл.

Нечто в этом духе мы еще будем обсуждать в главе 19, поскольку это считается «приемом из DHTML». А так вроде все довольно просто и понятно:

 document.images[0].src = "images/new.gif"
У объекта document есть несколько методов,
с которыми вы уже знакомы. Среди них метод document .writeln( ), он используется для написания одной строки текста и разметки на веб-странице. Для того же служит и метод document .write( ) .

Разница в том, что первый автоматически вставляет специальный знак перевода каретки (который, впрочем, все равно не распознается браузером, если только текст не заключен в теги <рге>),
а второй этот знак не вставляет.

Существует возможность очистить текущую страницу и
фактически создать вручную новую. Это делается следующим образом. Сначала очищаем страницу полностью: document. open( ).

Затем с помощью document, write О записываем в нее все что нужно. Теперь document. close( ) — и новая страница готова!

Рассмотрим листинг 18.2.

Листинг 18.2. Персонализация с использованием формы

<!DOCTYPE html PUBLIC "\//W3C//DTO XHTML1.0 Transitional//EN""http://www.w3.org/TR/xhtmll/DTD/xhtmll-transitional .dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><title> Страница персонализации </title><script type = "text/javascript"><!-- Прячем кодfunction personalizePage О{ var userName = personal Form.myName.value:document.open( )document. write("<html><head><title>HoBый документ</title></head>")document.write("<body><h1> Приветик. " + userName + "</h1>")document.write("<p>ЭTa страница созданаспециально для <b>тебя/b>! :-)</р>")document.write("</body></html>")document. close( ) } // закончили прятаться --></script></head><body><h1>Страница персонализации и авторизации</h1><р>Добрый день! Введите свое имя,затем щелкните на кнопке "Дальше". Содержимое страницыизменится. <bг /> Обратите вникание на то,что URL при этом не изменится !</р><form name="personalForm">Введите свое имя: <input type="text" name="myName"><input type=" button"name="personalButton" уа!ие="Дальше" onclick="personalizePage()" /></form></body></html>
В этом примере следует обратить внимание не только на метод document . open( ), но и на то, что на самом-то деле страница не изменяется. Выражение var userName = persona 1 Form. myName. value;

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

Если бы изменилось значение location. href), нам пришлось бы немного потрудиться, прежде чем получить доступ к тому же значению. На рисунке 18.2 демонстрируется листинг 18.2 в действии.

 

 

Рис. 18.2. Страница до (сверху) и после (снизу) запуска скрипта

JavaScript и формы HTML

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

Объект form

Для начала разберемся с тем, как создать несколько форм. Дело в том, что каждая форма будет иметь свое собственное имя (для этого используется значение атрибута name элемента <form>). А значит, получить доступ к элементам формы будет несложно. Итак, сначала даем имя (name="MyForm"), потом получаем доступ к любым элементам:

var name = document.myForm.custName.value
Вы знаете, как передать в функцию значение, указатель или же вообще ничего не передать и предоставить функции
возможность прямого доступа к форме с применением объекта document.

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

 var name = document.forms[0].custName.value:
Иногда бывает нужно организовать автоматический доступ к формам. Попробуй те в этом случае поступить следующим образом:

for (x=0: х<3: х=х+1) {var formName[x] = document.forms[x] name  }
С помощью такого цикла for можно все имена форм записать в массив, тем самым организовав независимый доступ к
каждой из них (formName[x]).

Все объекты формы, независимо от того, каким образом осуществляется доступ к ним, имеют свои наборы свойств, как и документ, окно. Свойства объекта form, в частности, следующие:

action. URL. В сущности, то же самое, что атрибут acti on элемента <form>.

method. To же самое, что атрибут method элемента <form>.

name. Имя формы (то же самое, что атрибут name элемента <form>).

length. Число элементов input, textaгеа и sel ect в форме.

target. Целевое окно или фрейм.

elements. Массив, в котором содержатся все элементы input, textarea и select
У объекта form есть, конечно, и свои методы, среди которых reset ( ), submit ( ), очевидного предназначения.

Обработка ошибок на форме с помощью JavaScript

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

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

Листинг 18.3. Проверка данных в формах с помощью JavaScript

<!DOCTYPE html PUBLIC "\//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtmll/DTD/xhtmll-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head><title> Страница персонализации </title><meta http-equiv="Content-Script-Type"content="text/javascript"><script><!-- Прячем кодfunction zipCheckOvar zipStr = custForm.zipCode.value;if (zipStr == "") {аlегt("Введите шестизначный индекс, пожалуйста"); return(-1); if (zipStr.length != 6) {alert("Индекс должен содержать 6 цифр!");return(-l);return();function checkSend ( ) (var passCheck = zipCheck( ): If (passCheck == -1) { return;} else{custForm.submitO: //Закончили прятаться --> </schpt></head><body><h1>Пожалуйста, заполните форму :</h1><form action="cgi-bin/address.pl" method="post"
 name="custForm"> <pre>Имя: <input type="text" size="20" name="name">Адрес: <input type="text" size="50" name="address">Город: <input type="text" size="30" name="city">Страна: <input type="text" size="30" name="state">Индекс: <input type="text" size="6" name="zipCode"onBlur= "zipCheck()">E-mail: <input type="text" size="40" name="email">«input type="button" уа!ие="0тправить" onclick ="checkSend()"></form></body></html>
Обработка формы начинается при возникновении события onBlur, то есть при потере фокуса поля ввода индекса, либо при нажатии клавиши Tab, либо с помощью мыши. Обработчик запускает функцию zipCheck, которая проверяет введенный почтовый индекс на корректность. Если поле осталось пустым, выдается окошко ] с напоминанием о том, что это поле следует заполнить. Это делается путем проверки значения строковой переменной:

 if (zipStr = "") {
Если введено больше или меньше 6 цифр, также выдается предупреждение. На этот
раз проверяется значение свойства length. А именно:

 if (zipStr.length != 6) { .
Если пользователь сделал все правильно, продолжается нормальная работа.
Конечно, пользователь может проигнорировать предупреждение или изменить его,
но так, что оно останется некорректным. Для этого случая предусмотрен повтор
ный вызов zipCheck из функции checkSend:

 var passCheck = zipCheck( ):
И если индекс по-прежнему остался неправильным, функция zipCheck вернет зна
чение-1, проверяемое с помощью checkSend:

 if (passCheck = -1) {  return;
  }
Так что если и на этот раз индекс введен неверно, то функция checkSend верне пользователя на продолжение заполнения формы. В общем, получилась много ступенчатая защита от неправильного ввода.

Если пользователь наконец набрал на клавиатуре шесть цифр, форма подтверждается:

 

Рис. 18.3. Если введен неправильный индекс, появляется окно с предупреждением

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

Итак, расширенная функция zipCheck( ) может выглядеть следующим образом:

function zipCheckOvar zipStr = custForm.zipCode.value:if (zipStr == "") {аlегt"Введите шестизначный индекс, пожалуйста");return(-l):if (zipStr.length != 6) {alert("Индекс должен содержать 6 цифр!"): return(-l):for (х = 0: x < 6; x++) if ((zipStr.charAt(x) < "О") | (zipStr.charAt(x) > "9")){аleft("Индекс должен состоять только из цифр!"): return(-l);  } return(O); }
Итак, мы добавили еще одну проверку. Она начинается с цикла for, чтобы прог амма могла произвести необходимое количество итераций, охватив всю длину поля ввода:

 for (х = 0: х < 6; х++)
Используя цикл for, мы можем последовательно перебрать все значения массива zipStr (а ведь строка представляет собой лишь особый вид массива!) с номерами от 0 до 5.

В цикле находится условное выражение if, — собственно говоря, именно оно и проверяет, являются ли символы цифровыми:

 if ((zipStr.charAt(x) < "О") || (zipStr.charAt(x) > "9")) {
Знак || означает логическое «или». Все приведенное выражение переводится на человеческий язык так: «Если символ меньше чем 0 или больше чем 9».

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

 alert("Индекс должен состоять только из цифр!"): return(-l);
Если же выражение if принимает значение «ложь», то команды, содержащиеся внутри, пропускаются, и предполагается,
что пользователю удалось ввести все правильно.

JavaScript на клиентской машине

Одним из преимуществ JavaScript является то,
что этот язык встраивается прямо в веб-страницу и вам не нужно заботиться о CGI-скриптах.

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

Листинг 18.4. Форма, обрабатываемая на стороне клиента


<!DOCTYPE html PUBLIC "\//W3C//DTD XHTML  1.0 Trans1tional//EN" "http://www.w3.org/TR/xhtmll/DTO/xhtmll-transitional .dtd"> <html xmlns="http://www. w3.org/1999/xhtml "><head><title> Хотим знать ваша мнение!</title> <script> <! -- Прячем код function processformO{ var newline = "\n";van result_str = ""; var Forml = document . forml :result_str += Forml. first_name. value + "" + Forml. lastjiame. value + newline: resu1t_str += Forml. email .value + newline: for (x = 0: x < Forml.where. length: x++) {if (Forml. where[x]. checked) {result_str += Forml. where[x]. value + newline:break: }
if (Forml. desktop. checked) result_str += "Настольные компьютеры" + newline: if (Forml. notebook. checked) result_str += "Портативные компьютеры" + newline: if (Forml. peripherals. checked) result_str += "Периферия" + newline: if (Forml. software. checked) result_str += "Программное обеспечение" + newline:document. form2. results. value = result_str; return:</script>
 </head><body><h1>Киберпространство. Обзоры, статьи. размышления</h1><form name = "form1" id = "forml"><table cellpadding="5"><tr><td>Имя: </td><td> <input type="text" name="first_name" size="40" maxlength="40"</tr><tr><td>Фамилия: </td><td><input type="text" name="last_name" size="40" maxlength="40" /></td> </tr><tr><td>E-mail: </td><td><input type="text" name="email" size="40" maxlength="40" /></td></tr></table><p><b>Откуда вы узнали об этом сайте?</b></р><input type="radio" name="where" уаluе="Интернет" checked="checked" /поисковая программа
 в Интернете или Интернет-ссылка<bг /><input type="radio" name="where" vаluе="Реклама" />Реклама по радио или телевидению<bг />«input type="radio" name="where" vаluе="Упоминание в прессе" />Из газеты<bг /><input type="radio" name="where" value="Дpyroe" />Другое<bг /></p><b>0 какой продукции вы хотели бы узнать подробнее?(Включите все нужные флажки)</b><bг />«input type="checkbox" name="desktop" />Настольные компьютеры<input type="checkbox" name=" notebook" /> Портативные компьютеры<input type="checkbox" name="peripherals" />Периферия<input type="checkbox" name="software" />программное обеспечение</p>«button name="submit" type="button" onclick="processform()"><span style="font-family: Arial. Helveticaifont-variant: small-caps: font-size: 12рt">Подтвердить данные</sраn></button><button name="reset" type="button"><span style=" font -family: Arial. Helvetica:  font-variant: small-caps: font-size:12рt>Очистить форму</sрап></button></form><hr /><form name="form2" id = "form2" action="mailto:survey@fakecorp.net"><р>Тщательно проверьте свои записи. Если все верно, можете ввести комментарии в текстовомполе, расположенном чуть ниже. Чтобы отправить форму, щелкните на кнопке "Отправить". </р><textarea name=" results" rows="10" cols="40">
 Текстовое поле для ввода комментариев и замечаний</textarea>«button name=" submit" type="submit">«span sty! e-"font-f ami ly: Arial.  Helvetica: font-variant: small-caps; font-size:12рt>Отправить</sрап></button></form></body> </html>
Этот скрипт с методической точки зрения очень полезен для изучения.

Скрипт берет значения, введенные пользователем в первой форме, и помещает их в текстовом виде во вторую форму. Затем можно редактировать данные, например добавлять комментарии (рис. 18.4). Наконец, при нажатии на кнопку SEND IT! (Отправить!) вся накопленная информация отправляется по электронной почте.

 

Рис. 18.4. Пользователь может отредактировать данные перед отправкой

ПРИМЕЧАНИЕ

Хотя данные придут в формате «post» (глава 15), однако обрабатывать придется всего лишь одно поле, благодаря предварительному анализу, производящемуся в скрипте.

Этот пример показывает, как важно получать корректные значения флажков и переключателей. В листинге 18.4 демонстрируются два способа, которыми это можно сделать. Для начала обратимся к переключателям. Нам нужно опреде лить, какое положение селективной кнопки выбрано, тогда мы сможем работать с соответствующими данными.

Значения переключателей хранятся в специальных массивах, а следовательно, мы можем получить доступ к ним с помощью цикла:

 for (х = 0: х < Forml. where. length; x++){ if (Forml. where[x]. checked){ result_str += Forml. where[x] .value + newline: break:}
В свою очередь, все переключатели тоже хранятся в массиве объектов, имена кото рых определяются при помощи атрибута name, указываемого при их создании. В на шем примере name="where".

С каждым экземпляром where можно использовать свойство checked для того, чтобы определить, в каком положении находится реключатель.

Когда мы найдем тот объект where, свойство checked которого равно true, это будет означать, что именно его value нам и нужно.

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

Когда он его находит, цикл for завершается (командой break), а со значением производятся определенные действия. В данном случае оно добавляется к строке result_str.

Второе, что показано в этом примере, — это работа с наборами флажков. И здесь тоже нужно проверять состояние свойства checked.

Но поскольку каждый флажок имеет свое собственное имя (name), то нет необходимости хранить их в каком-то массиве или использовать цикл для их перебора. К каждому флажку требуется индивидуальный подход, у каждого из них лично нужно выяснить, является ли он checked. Если это так, то используется его значение:

if (Forml.desktop.checked) result_str +="Настольные компьютеры" + newline:if(Forml.notebook.checked) result_str += "Портативные компьютеры" + newline;if(Forml,peripherals.checked) result_str +="Периферия" + newline; if(Forml.software.checked)result_str += "Программное обеспечение" + newline;
Если ([шажок установлен, то его значение добавляется к result_str. В противном случае скрипт переходит к следующему условному оператору.

Переадресация, фреймы и JavaScript

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

Переадресация браузера

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

При переадресации браузера используется объект,
который мы до сих пор не упоминали. Он называется navigator.

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

Например, в переменной navigator.appName xpaнится полное имя приложения, объект navigator.userAgent сообщит вам общую информацию об уровне совместимости данного ПО (например, Mozi 11 а/4.0 может на поверку оказаться любой Netscape-совместимой программой уровня 4.0).

Наконец, navigator.appVersion выдаст номер версии браузера.Итак, первое, что вы может сделать, — это создать документ, в котором будут отражены все свойства браузера, получившего доступ к нему:

<script type="text/javascript">document.writeln ("navigator.appName; " + navigator.appName + "<br \/>"): document.writeln ("navigator.userAgent:
" + navigator.userAgent + "<br \/>"):document.writeln ("navigator.appVersion: " + navigator.appVersion
 + "<br \/>");</script>
Хотя эта информация является бесспорно полезной, пока непонятно, как из этого извлечь какую-нибудь пользу.

А польза может быть такой: узнать версию брау-зера и в соответствии с ней загрузить ту или иную страницу. Но для этого скрипт должен проанализировать текстовые данные и понять, что из этого набора символов является именем приложения, что — версией, и т. д.

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

Листинг 18.5. Переадресация браузера

<!DOCTYPE html PUBLIC "\//W3C//DTO XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtmll/OTD/xhtnill-transitional .dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><title> Детектор браузеров </title><script><!-- Прячем кодvar browserAppName = navigator.appName:if (browserAppName == "Netscape") {window.location = "net_index.html";} else {if (browserAppName == "Microsoft Internet Explorer"){ window.location = "ie index.html";else {window.location = "index.html";</script> </head> <body><h1>3дравствуйте. я ваша тетя-детектор браузеров !</h1><р>Если эта страница не обновляется, ваш  браузер несовместим с JavaScript или поддержка JavaScript отключена. Пожалуйста, нажмите <а href="index.html">3flecb</a>. чтобы хотьчто-нибудь увидеть.</р> </body> </html>
Наверное, вы уже заметили некоторые архитектурные излишества этого листинга: если надо было определить всего лишь, совместим ли браузер с JavaScript или нет, к чему же столько трудов?

Хватило бы и такой команды: window, location = "newpage.html" Если страница не обновляется, то можно предположить, что JavaScript и браузер пользователя незнакомы.

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

ПРИМЕЧАНИЕ

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

Как написать меню ссылок на JavaScript

Говоря об элементах формы в этой главе, мы опустили элемент <select>.

Сейчас мы восстановим справедливость и
создадим навигационное меню,

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

И для этого мы воспользуемся элементом <select>. Листинг 18.6 показывает это в действии.

Листинг 18.6. Меню <select> и JavaScript


<!DOCTYPE html PUBLIC "\ //W3C//DTD XHTML 1.0 Transitional//EN"'http://www.w3.org/TR/xhtmll/DTD/ xhtmll-transitional.dtd"> <html xmlns="http: //www.w3.org/1999/xhtml"> <head><title> Смена страницы </title>( «script type="text/javascript"><!-- function changePage(theSelect)
{
var x = theSelect.selectedlndex;window, location. href =theSelect.options[x].text:</script></head><body><div align="center"><form name="changeForm"><select name="changeSelect" onchange="changePage(this)"><option selected="se!ect">Выберите страницу</орtion><option>index. html </option><option>products. html </opti on><option>service. html </option><option>about. html </opt i on><option>help. html</opt ion> </select></p></form></div><hr />пожаловать на сайт!</111><р>Какой-то текст...</р></body></html>

С меню <select>, в отличие от других элементов форм, не ассоциировано никакое значение. Вместо этого используется то, что содержится в контейнерах <option>.

Этот текст сохраняется в свойстве text объекта. Кроме того, выбранное значение сохраняется в свойстве selected Index.

С помощью следующего кода скрипт просто передает значение в selectedlndex. Затем оно используется для получения доступа к тексту выбранного пользователем пункта (для этого существует массив option):

 

 function changePage(theSelect) {var x = theSelect.selectedlndex:window.location.href = theSelect.options[x].text:
}

Таким образом и следует извлекать значения из меню <select>.

На рисунке 18.5 показана такая страница в действии.

 

Рис. 18.5. Навигация с помощью меню <select> и JavaScript

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

Однако есть и другой подход — использовать фреймы. Именно об этом мы и поговорим далее.

JavaScript и фреймы

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

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

Во-первых, документ, содержащий <frameset>. Это та цементирующая основа, которая скрепляет вместе все разрозненные страницы. Во-вторых, страница навигации, включающая в себя меню <select> (подробности в предыдущем параграфе). Всего несколько изменений -и это меню можно применить к фреймам.

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

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

Рассмотрим листинг 18.7, содержащий <frameset>.

Листинг 18.7. Документ, задающий набор фреймов


<!DOCTYPE html PUBLIC "\//W3C//DTD XHTML1.0 Frameset//EN""http://www.w3.org/TR/xhtml1/ DTD/xhtml1- frameset.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><title>Навигатор статей</title></head><frameset rows="150. *"><frame src="navigate.html" /><frame src="default.html" name="main_viewer" /> </frameset>
Создадим navigate.html — страницу навигации.

Она будет расположена вверху страницы и
организована в виде меню <sel ect>.

Код документа показан в листинге 18.8,
причем целевой объект ссылок теперь задается следующим образом: top.main_viewer, location. href.

Как вы, вероятно, помните из главы 12, top — это обозначение для окна браузера.

То же самое обозначение используется и в объектной модели документа, в которой есть все фреймы. А раз они там есть, значит, им можно присвоить URL.

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

Создается массив адресов, обращение к которым происходит по номеру пункта меню. Нужно организовать этот массив таким образом, чтобы записи <option> в <select> соответствовали списку URL.

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

Листинг 18.8. Страница navigate.html

<!DOCTYPE html PUBLIC "\//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtmll/DTD/xhtmll-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><title>Страница навигации</title><script type="text/javascript><!------function changePage(theSelect) {pageArray = new Array ("default, html", "articlel.html". "article2.Titml".
"article3.html"."article4.html". "article5.html"); var x = theSelect.selectedlndex;top.main_viewer.location.href = pageArray[x];} // .-></schpt></head><body style="background-color: yellow"><div align="center"><b1>Архив статей на FakeCorp</h1><form name="changeForm"><р>Какую статью вы хотите прочесть сейчас?</р><р> <select name="changeSelect" onchange="changePage(this)"> <option selected="select">Haчaльнaя страница</орtiоn> <орtiоn>Память типа RAM</option><орtiоn>Технология изготовленияжестких дисков</орtiоn> <орtiоnп>Как выбрать монитор</орtiоn><option>KaK выбрать новый пpoцeccop</option> <орtiоn>Решение проблем с операционнымисистемами</орtiоn> </select></form></body> </html>
Теперь нам нужна страница default . html , которая будет появляться вместе с набором фреймов. Эта страница представляет собой простой XHTML-документ, который дает пользователю определенные пояснения относительно интерфейса, здесь же можно прочитать новости сайта, а также перейти на вариант страницы, не содержащий фреймов.

Листинг 18.9 — это код страницы default.html.

Листинг 18.9. Страница default.html


<!DOCTYPE html PUBLIC "\//W3C//DTD XHTML 1.0 Transitional//EN""http : //www . w3 . org/TR/xhtml 1 /DTD/xhtml 1 -transi ti onal  . dtd"><html xmlns="http: //www.w3.org/1999/xhtml"><head><title>Домашняя страница</title></head><body style="margin: 24pt"><h1>Apxив статей FakeCorp</h1><p>C помощью меню, расположенного вверху, выберите статью. Она автоматически загрузится в этом окне. Для возврата на данную страницувыберите в меню "Начальную страницу".</р><р>Если вы хотите посетить версию сайта без фреймов или если ваш браузер не поддерживает JavaScript, нажмите <а href="noframes.html">здесь</а>.</р><h2>0бновления! </h2><p><strong>10/13 --</strong> Мы только что опубликовали статью, в которой рассказываетсяо новейших технологиях создания памяти спроизвольной выборкой (RAM). В ней даются советы о том. как правильно выбрать памятьдля своего компьютера. Приводится много данных,в том числе статистических, которые касаются различных характеристик, в том числе соотношения параметров цены и надежности.</р><p><strong>10/5 --</strong> Читайте статью обобновлении процессора. В ней вы сможете найтимного полезной информации, которая поможет вам  решить, настало ли время сменить процессор своего ПК, и если настало, то что выбрать.</р></body></html>
Теперь, предполагая, что все статьи на месте и файлы называются ровно так, как про них написано в HTML-коде фреймов, мы можем запустить страницу, в которой описывается весь набор фреймов, и посмотреть результат (рис. 18.6).

 

Рис. 18.6. С помощью <frameset> и специального меню <select> можно сделать интерфейс,
основанный на JavaScript

Резюме

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

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

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

В следующей главе мы продолжим свое знакомство с JavaScript и его совместной работе с технологией CSS. Такой подход часто называют Динамическим HTML (DHTML).

Copyright © 2006-09.