Проект Порталус


AboutPC
30/06/2003 г № 7
Главная
Новости
Безопасность
Антиспам
*nix
Железо
Софт
Игры
HTML
FAQ
Веб-дизайн
Разное
:: контакты
:: реклама
:: сайт
 

Содержание:

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

7.2. Страница, управляемая при помощи мыши

7.2a Динамическое управление позиционированием элементов

7.3. Страница, управляемая с клавиатуры

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

7.1. Ввод данных пользователем в формы HTML

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

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

Получение информации от пользователя

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

Итак, возьмем заголовок и правую часть веб-страницы. Только добавим ссылку на страницу “Услуги” и снимем ее с “Книги отзывов”:

<DIV CLASS="rght">

<DIV CLASS="lnk"><A HREF="main.html">УСЛУГИ

</A>

</DIV> <DIV CLASS="lnk">

<A HREF="prices .html">ЦЕНЫ

</A>

</DIV>

<DIV CLASS="lnk">

<A HREF="forml.html">Форма 3AKA3A

</A>

</DIV>

<DIV CLASS="lnk">

<A HREF="history.html">История

<SPAN STYLE="letter-spacing: -3px; ">KOMПAHИИ

</SPAN>

</A>

</DIV>

<DIV CLASS="lnk">Книга OT3ЫBOB</DIV>

А в левую часть страницы давайте поместим форму. Для этого сначала добавим специальный тег <FORM>, без которого невозможно будет отправить данные на сервер обычными средствами. Здесь нам потребуется указать атрибут METHOD=, с помощью которого броузер определяет способ отправки данных: в виде “добавки” к строке URL (метод get) или в виде блока данных (метод post). В качестве значения атрибут ACTION= необходимо указать URL-адрес сервера, куда отправятся данные. Здесь можно также указать адрес электронной почты (с префиксом mailto:) — в этом случае данные формы отправятся по указанному адресу. В нашем случае давайте укажем гипотетический URL-адрес сервера cgi.lentyay.com, где обработка данных формы будет происходить с помощью какого-нибудь CGJ-сценария:

<FORM ACTION="http://cgi.lentyay.corn/guest.cgi" METHOD="post">

В конце формы должен стоять закрывающий тег </FORM>. Все, что находится внутри, можно будет сообщить серверу. Для отправки данных формы традиционно используется кнопка с названием Submit (Отправить). Для ее создания можно использовать тег <INPUT> с атрибутом TYPE="submit":

<INPUT TYPE="submit" VALUE="Отправить">

Атрибут VALUE= при этом определяет надпись на кнопке. Если его не задать, то на кнопке будет написано Submit. Какие же данные будут отправлены? Для начала давайте спросим у пользователя его имя, выделив для этого небольшое однострочное текстовое поле, и мнение об услугах фирмы, для чего выделим многострочное текстовое поле.

Поля для ввода текста

Чтобы создать однострочное текстовое поле, нужно также воспользоваться тегом <INPUT>, но уже с атрибутом TYPE="text". При этом его ширина задается с помощью атрибута SIZE=. Чтобы программе обработки данных (или человеку, который будет в этих данных разбираться) было понятно, какие данные к какому полю относятся, желательно для каждого поля указать атрибут NAME=. В данном случае мы запрашиваем у пользователя его имя, поэтому пусть значением этого атрибута будет слово Имя (по-английски тоже Name):

<INPUT TYPE="text" NAME="Name" VALUE="Аноним" SIZE="30">

При этом атрибут VALUE= определяет, что будет изначально написано в текстовом поле. Обратите внимание на то, что атрибут SIZE= определяет только видимую ширину текстового поля, но вовсе не ограничивает количество вводимых пользователем символов. Если же надо ввести такое ограничение, то следует пользоваться атрибутом MAXLENGTH=.

— Хорошо, — скажете вы, — но как пользователь узнает, что от него требуется ввести в это поле?

Чтобы дать ему “подсказку”, можно просто написать ее текст перед текстовым полем:

Ваше имя: <INPUT TYPE="text" NAME="Name" УАШЕ="Аноним" SIZE="30">

Однако лучше воспользоваться тегом <LABEL>, который был введен в Internet Explorer версии 4. Он гарантирует привязку метки к полю ввода. В нем нужно указать единственный атрибут FOR=, значение которого должно содержать имя поля ввода:

<LABEL FOR="Name">Baшe имя:</LABEL>

<INPUT TYPE="text" NAME="Name" VALUE="AHOHИM" SIZE="30"><BR>

Теперь давайте создадим многострочное текстовое поле для ввода мнения клиента об услугах фирмы. Для этого необходимо использовать тег <TEXTAREA>. В нем можно с помощью атрибутов COLS= и ROWS= определить количество символов в строке и число строк текстового поля:

<TEXTAREA COLS="30" ROWS="4" NAME”"Opinion" STYLE="vertical-align: middle;"></TEXTAREA>

Как видите, здесь мы также определили атрибут NAME=. А поскольку это текстовое поле является многострочным, мы применили еще и стилевое свойство vertical-align, чтобы “подсказка” пользователю расположилась по центру (по умолчанию она располагается внизу).

Кроме того, не забудьте поставить закрывающий тег </TEXTAREA>, поскольку все, что находится между открывающим и закрывающим тегами, будет трактоваться как содержимое текстового поля. Если не поставить закрывающий тег, все последующее содержимое веб-страницы окажется в текстовом поле, причем в виде исходного текста!

Теперь давайте добавим еще одну “традиционную” кнопку, при нажатии на которую все поля формы очищаются (или приобретают исходные значения, определенные атрибутом VALUE= — в данном случае при ее нажатии в поле Ваше имя появится запись Аноним). Такую кнопку можно создать с помощью тега <INPUT> с атрибутом <TYPE="reset">:

<INPUT TYPE="reset" VALUE ="Очистить форму">

Как и в случае с кнопкой Submit, значение VALUE= здесь определяет надпись на кнопке. Если этот атрибут не установлен, на кнопке будет написано: Reset. Давайте посмотрим, что v нас получается в целом.

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

<HTML>

<HEAD>

<TITLE>Baш отзыв</ТIТLЕ>

<STYLE> BODY { background-color: #D2FFFF;

color: #003737; background-image: url("Images\grad2.jpg");

background-position: right;

background-repeat: repeat-y;

} HI { text-align: center } A:link,A:active,A:visited {

color: #006A6A;

} A:hover { font-weight: bold; text-decoration: none;

} .hdr { position:

absolute;

left: 50px;

top:

10px;

text-align:

center;

font-family:

OdessaScriptFWF, fantasy; font-size: 60px;

font-weight: 900;

width: 90%;

height: 100px;

letter-spacing: 0.05em;

line-height: 100px;

filter: shadows- border:

10px outset #003163;

color: #3163CE; }

.1ft {

position: absolute;

font-size: meduim;

left: 10px;

top: 160px;

width: 160px;

height: 400px;

overflow-x: visible;

} .Ink {

border-width: thick;

border-style: ridge;

margin: 10рх;

padding: 5px;

border-color: #319CFF;

background-image: url("Images\backlnkl.jpg") ; color: red;

text-align: center; }

.Ink A {

text-decoration: none; color: white;

} .logo {

position: absolute;

left: 150; top: 220;

z-index: -5;

} </STYLE>

</HEAD>

<BODY>

<DIV CLASS="hdr">Фиpмa&nbsp;&laquo;ЛEHTЯЙ&raquo;</DIV>

<DIV CLASS="rght">

<DIV CLASS="lnk">

<A HREF="main.html">УСЛУГИ</A>

</DIV> <DIV CLASS="lnk">

<A HREF="prices .html">ЦЕНЫ</A></DIV>

<DIV CLASS="lnk">

<A HREF="forml .html">ФOPMA 3AKA3A</A> </DIV>

<DIV CLASS="lnk">

<A HREF="history.html">ИСТОРИЯ <SPAN STYLE="letter-spacing: -3рх; ">КОМПАНИИ</SРАN></А>

</DIV>

<DIV CLASS="lnk">KHHГA OT3ЫBOB</DIV>

</DIV> <DIV CLASS="lft">

<Н1>Ваш отзыв с наших услугах</Н1>

<DIV ALIGN="center">

<FORM ACTION="http://cgi.lentyay.corn/guest.cgi" METHOD="post">

<LABEL FOR="Name">Bame имя:</LABEL>

<INPUT TYPE="text" NAME="Name" VALUE="Аноним" SIZE="30">

<BR>

<LABEL FOR="Opinion">Baшe мнение:</LABEL>

<TEXTAREA COLS="30" ROWS="4" NAME="Opinion" STYLE="vertical-align: middle; "></TEXTAREA>

<BR> <INPUT TYPE="submit" VALUE="Отправить">

<INPUT TYPE="reset" VALUE="Очистить форму"> </FORM> </DIV> </DIV>

<IMG CLASS="logo" SRC="Imqes/logo6.gif" WIDTH="500" HEIGHT="346" BORDER="0">

</BODY>

</HTML>

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

Списки

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

Выбор возрастной категории можно организовать в виде раскрывающегося списка. Для создания такого списка используется тег <SELECT>. Между ним и его закрывающим тегом </SELECT> можно поместить несколько пунктов будущего списка. Каждый из них должен начинаться с тега <OPTION>. В данном случае мы можем написать так:

<SELECT NAME="Age" SIZE="1">

<OPTION VALUE="10">менее 20

<OPTION VALUE="20">20&ndash;30

<OPTION VALUE="30">30&ndash;40

<OPTION VALUE="40">40&ndash;50

<OPTION VALUE="50">50&ndash;60

<OPTION VALUE="60">6onee 60 </SELECT>

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

Вы, вероятно, обратили внимание еще на один атрибут тега <SELECT> — атрибут SIZE=. Здесь его значение равно 1 (кстати, это значение определено по умолчанию, так что можно было этот атрибут и не указывать). Если указать значение, большее 1, то в окне броузера вместо раскрывающегося списка отобразится так называемый прокручиваемый список. Если же надо дать пользователю возможность выбора сразу нескольких пунктов из списка, то в теге <SELECT> надо установить атрибут MULTIPLE=.

Переключатели

помощью такого списка можно было бы организовать и выбор пола, однако давайте применим для этого другой элемент формы — переключатели. Они употребляются группами, в которых только один переключатель может быть включен одновременно. Каждый из переключателей создается с помощью тега <INPUT> с атрибутом TYPE="radio". В группу будут объединены те переключатели, теги которых имеют одинаковые значения атрибута NAME=. Например, в данном случае мы можем написать так:

<LABEL FOR="Sex">Baш пол:</LABEL>

<INPUT TYPE="radio" NAME="Sex" VALUE="М">Мужской <INPUT TYPE="radio" NAME="Sex" LABEL="F">Женский

Как видите, значение атрибута NAME= одинаково у обоих тегов <INPUT>, поэтому пользователь не сможет выбрать оба пункта одновременно (при выборе одного из пунктов выбор предыдущего отменяется). Кстати, в этом примере изначально не выбран ни один из пунктов. Если же надо, чтобы какой-либо пункт был выбран заранее, то необходимо в соответствующем теге <INPUT> установить атрибут CHECKED, например, вот так:

<INPUT TYPE="radio" NAME°"Sex" VALUE="F" СНЕСКЕD>Женский

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

Флажки

Теперь давайте спросим пользователя о его интересах. Для этого органи зуем список из нескольких пунктов, которые он сможет отметить флаж ками. Каждый из пунктов такого списка создается с помощью все того же тега <INPUT>, однако теперь у него должен быть атрибут TYPE="checkbox". Впрочем, этот вариант практически ничем не отличается от предыдущего, кроме того, что пользователь может выбрать сразу несколько пунктов или даже все. Например:

<LABEL FOR="Interestsl">Baiim интересы :<BR></LABEL>

<INPUT TYPE="checkbox" NAME="Interestsl" VALUE="Computers">КОМПЬЮТЕРЫ

<INPUT TYPE="checkbox" NAME="Interests2" VALUE="Sports">Cnopт

<INPUT TYPE="checkbox" NAME="Interests3" VALUE="Art">Иcкyccтво

<INPUT TYPE="checkbox" NAME="Interests4" VALUE="Science">Hayкa

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

Давайте посмотрим, что у нас получается (для экономии места приведем текст не всей страницы, а только ее левой части):

<DIV CLASS="lft"> <Н1>Ваш отзыв о наших услугах</Н1>

<DIV ALIGN="center"> <FORM ACTION="http://cgi.lentyay.corn/guest.cgi" METHOD="post"> <LABEL FOR="Name">Baшe имя:</LABEL>

<INPUT TYPE="text" NAME="Name" VALUE="Аноним" SIZE="30"><BR><BR> <LABEL FOR="Age">Baш возраст:</LABEL>

<SELECT NAME="Age" SIZE="1">

<OPTION VALUE""10">менее 20 <OPTION VALUE="20">20&ndash;30 <OPTION VALUE="30">30&ndash;40

<OPTION VALUE="40">40&ndash;50

<OPTION VALUE="50">50&ndash;60

<OPTION VALUE="60">6onee 60 </SELECT>

<BR><BR>

<LABEL FOR="Sex">Baш noл:</LABEL>

<INPUT TYPE="radio" NAME="Sex" VALUE="М">Мужской

<INPUT TYPE="radio" NAME="Sex" VALUE="F">Женский

<BR><BR> <LABEL FOR="Interestsl">Baши интересы:<BR></LABEL>

<INPUT TYPE="checkbox" NAME="Interestsl" VALUE="Computers">Компьютеры

<INPUT TYPE="checkbox" NAME="Interests2" VALUE="Sports">Cnopт

<INPUT TYPE="checkbox" NAME="Interests3" VALUE="Art">Иcкyccтво

<INPUT TYPE="checkbox" NAME="Interests4" VALUE="Science">Hayкa

<BR><BR> <LABEL FOR="Opinion">Baшe мнение:</LABEL>

<TEXTAREA COLS="30" ROWS="4" NAME="Opinion" STYLE="vertical-align: middle; "></TEXTAREA>

<BR><BR> <INPUT TYPE="submit" VALUE="Отправить">

<INPUT TYPE="reset" VALUE="Очистить форму">

</FORM>

</DIV>

</DIV>

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

Группы элементов формы

Неплохо бы было еще логически объединить то, что связано со сведениями о пользователе, и то, что связано с его мнением. Для такого группирова ния элементов форм в HTML 4.0 был введет тег <FIELDSET>. Все, что нахо дится между ним и его закрывающим тегом </FIELDSET>, будет обведено в рамку и озаглавлено так, как указано в теге <LEGEND>. Теги <FIELDSET> и <LEGEND> поддерживаются пока только в Internet Explorer версии 4 и выше, а броузер Netscape начал поддерживать их только в шестой версии. Кроме того, элементы <FIELDSET> пока не очень хорошо позиционируются на веб- страницах. Как вы увидите в следующем примере, для корректного цент рирования их на странице (в Internet Explorer 5) нам пришлось поместить всю форму в центрированную таблицу и, кроме того, отдельно центриро вать то, что расположено между каждой парой тегов <FIELDSET> и </FIELDSET>.

Тег <FIELDSET> можно употребить следующим образом:

<FIELDSET Т1ТЬЕ="Сведения о клиенте"> <LEGEND ALIGN="left">Paccкaжитe о ce6e</LEGEND>

После этого можно поместить несколько элементов формы и поставить закрывающий тег </FIELDSET>. В броузере Internet Explorer значение атрибута TITLE= выводится в качестве всплывающей подсказки при наведении мыши на содержимое элемента <FIELDSET>. Кстати, это относится также и к другим тегам, которые могут иметь атрибут TITLE=. Можно, например, установить его даже у элемента <BODY>. А то, что находится между тегами <LEGEND> и </LEGEND>, будет вынесено в заголовок рамки.

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

<FIELDSET TITLE="Baшe мнение">

<LEGEND ALIGN=left>Baшe Mнeниe</LEGEND>

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

Этот недостаток можно устранить, используя специальный тип тега <INPUT>. Если в этом теге установить атрибут TYPE="file", то пользователь увидит на экране текстовое поле для ввода имени файла, а рядом с ним будет расположена кнопка, при нажатии на которую откроется стандартное окно выбора файла. Имя выбранного файла будет автоматически введено в текстовое поле. Можно написать, например, так:

<LABEL FOR="Opinion-File">BBennTe имя файла с описанием вашего мнения: </LABEL><BR>

<INPUT TYPE="file" NAME="Opinion-File" SIZE="30">

Как видите, с помощью атрибута SIZE= здесь также можете задать ширину текстового поля.

Давайте посмотрим, что у нас получается в целом (как и в прошлый раз, мы приводим текст только для левой части страницы, все остальное остается прежним).

<DIV CLASS="lft"> <Н1>Ваш отзыв о наших услугах</Н1>

<DIV ALIGN="center"> <TABLE WIDTH="75%"><TR><TD>

<FORM ACTION="http://cgi.lentyay.corn/guest.cgi" METHOD="post">

<FIELDSET Т1ТLЕ="Сведения о клиенге">

<LEGEND ALIGN="left">Paccжите о ce6e</LEGEND>

<DIV ALIGN="center">

<LABEL FOR="Name">Baшe имя:</LАВЕL>

<INPUT TYPE="text" NAME="Name" VALUE="AHOHИM" SIZE="30">

<BR><BR>

<LABEL FOR="Age">Baш возраст :</LABEL>

<SELECT NAME="Age" SIZE="1">

<OPTION VALUE="10">Meнee 20

<OPTION VALUE="20">20&ndash;30

<OPTION VALUE="30">30&ndash;40

<OPTION VALUE="40">40&ndash;50

<OPTION VALUE="50">50&ndash;60

<OPTION VALUE="60">6onee 60 </SELECT>

<BR><BR>

<LABEL FOR="Sex">Baш пол:</LABEL>

<INPUT TYPE="radio" NAME="Sex" VALUE="М">Мужской

<INPUT TYPE="radio" NAME="Sex" VALUE="F">Женский

<BR><BR>

<LABEL FOR="Interestsl">Baши интересы:<BR></LABEL>

<INPUT TYPE="checkbox" NAME="Interestsl" VALUE=" Computers ">Kомпьютеры

<INPUT TYPE="checkbox" NAME="Interests2" VALUE="Sports">Cnopт

<INPUT TYPE="checkbox" NAME="Interests3" VALUE="Art">Иcкyccтво

<INPUT TYPE="checkbox" NAME="Interests4" VALUE="Science">Hayкa

</DIV> </FIELDSET>

<BR>

<FIELDSET ТIТLЕ="Ваше мнение">

<LEGEND ALIGN="left">Bame мнение</LEGEND>

<DIV ALIGN="center">

<LABEL FОR="Орtion-Fi1е">Введите имя файла с описанием вашего мнения :</LABEL>

<BR>

<INPUT TYPE="file" NAME="Opinion-File" SIZE="30">

<BR><BR>

<LABEL FOR="Opinion-Text">Или просто выскажите свое мнение прямо здесь: </LABEL>

<BR>

<TEXTAREA COLS="30" ROWS="4" NAME="Opinion-Text" STYLE="vertical-align: middle; "></TEXTAREA>

</DIV>

</FIELDSET>

<BR>

<DIV ALIGN="center">

<INPUT TYPE="submit" VALUE="Отправить">

<INPUT TYPE="reset" VALUE="Очистить форму"> </DIV>

</FORM> </TD></TR></TABLE> </DIV> </DIV>

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

Другие элементы формы

Итак, запомним, что тег <INPUT> может использоваться в формах для создания самых разных элементов управления. Вид элемента зависит от значения атрибута TYPE= этого тега. Некоторые из этих значений мы уже рассмотрели. Теперь давайте просто перечислим оставшиеся:

<INPUT TYPE="password">

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

<INPUT TYPE="button">

А такая запись создает кнопку произвольного назначения. В отличие от кнопок типа Submit (Отправить) или Reset (Сброс), при нажатии на эту кнопку ничего не произойдет, если не написан соответствующий обработчик события (с обработчиками событий мы познакомимся в следующем разделе). Тег <lNPUTTYPE="button"> во многом аналогичен рассмотренному в главе 3 тегу <BUTTON>. Однако, в отличие от последнего, он не позволяет отображать на кнопках графику и другие нестандартные объекты. С другой стороны, будучи элементом формы, он доступен для обработки в броузере Netscape 4.

<INPUT TYPE="hidden">

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

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

 

 

автор: Народный мастер
сайт:  
мыло: kariera2001vit@mail.ru

 

 

вверх

7.2. Страница, управляемая при помощи мыши

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

Помните, как в примерах Главы 4 мы изменяли цвет гиперссылки при наведении на нее мыши? Это происходило с помощью псевдокласса :hover. Однако этот псевдокласс пока что определен только для тега <А>. А как быть, если мы хотим изменить цвет обычного текста при наведении на него мыши?

Рассмотрим, как это делается. Допустим, мы написали небольшую тесто вую страницу.

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

<HTML>

<HEAD>

<ТIТLЕ>Обработка событий мыши</ТIТLЕ>

</HEAD>

<BODY> Этот текст не изменит свой цвет. Этот текст изменит свой цвет, если навести на него мышь! Этот текст не изменит свой цвет.

</BODY>

</HTML>

Реакция на наведение

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

<DIV>Этот текст изменит свой цвет, если навести на него мышь!</DIV>

Чтобы при наведении мыши что-нибудь произошло, нужно добавить обработчик событий onMouseOver:

<DIV onMouseOver="">Этот текст изменит свой цвет, если навести на него мышь</DIV>

Итак, обработчик добавлен, однако пока он ничего не делает. В кавычки нужно поместить то действие, которое он должен выполнить. А что он дол жен сделать? Изменить цвет этого блока <DIV>, например, на красный. Доступ к свойствам текущего элемента осуществляется с помощью ключевого слова this:

<DIV onMouseOver="this.style.colors'red">Этот текст изменит свой цвет, если навести на него мышь!</DIV>

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

<DIV onMouseOver="this.style.color"'red'" onMouseOut="this.style.color='black'">Этот текст изменит свой цвет, если навести на него мышь!</DIV>

Теперь при наведении указателя мыши на эту строку, ее цвет изменится на красный, а при уводе указателя — обратно на черный. Можно также использовать и доступ по названию элемента. Например, если установить в этом блоке атрибут ID="text1", то можно будет написать так:

<DIV ID="textl" onMouseOver="textl.style.color='red'" onMouseOut="textl.style.color='black'">Этот текст изменит цвет, если навести на него мышь!</DIV>

<DIV ID="textl" onMouseOver="document.all.textl.style.color='red'" onMouseOut="document.all.textl.style.color”'black'">Этот изменит свой цвет, если навести на него мышь!</DIV>

Обратите внимание на то, что внутри кавычек расположен текст, написанный на языке JavaScript. Чтобы не загромождать текст HTML-документа, можно заранее определить соответствующие функции в разделе <HEAD>:

<HEAD>

<ТIТLЕ>Обработка событий мыши</ТIТLЕ>

<SCRIPT LANGUAGE="JavaScript">

function change() { document, all. textl. style. color="red";

} .function change2() { document.all.textl.style.color="black";

} //--> </SCRIPT> </HEAD>

а при определении обработчиков событий писать только имена функций:

<DIV ID="textl" onMouseOver="change()" onMouseOut="change2()">Этот текст изменит свой цвет, если навести на него мышь!</DIV>

Результат будет тот же, что и в прошлый раз.

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

<DIV ID="text2">Этот текст изменит свой цвет, если мышь навести на вторую строку!</DIV>

а потом соответствующим образом изменить функции:

function change() { document.all.textl.style.color="red";

document.all.text2.style.color="green";

} function change2() {

document.all.textl.style.coior="black";

document.all.text2.style.color="black"; }

Теперь при наведении мыши на вторую строку ее цвет будет изменяться на красный, а цвет третьей строки — на зеленый. К сожалению, здесь начинают сильно сказываться различия между броузерами. Доступ через метод documental! будет работать в Internet Explorer, но не сработает в Netscape. Чтобы этот пример мог работать в Netscape 6, необходимо доступ через метод document, all заменить на доступ через метод document. getElementByld( ). А как быть, если мы хотим, чтобы этот пример работал и в Internet Explorer, и в Netscape 6?

Учет различий между броузерами

Такие вопросы обычно решаются не просто. Но в данном случае мы можем осуществить проверку версии броузера и, в зависимости от ее результата, присвоить переменной textl либо значение document.all.textl, либо значение document.getElementByld("text1"). А затем в функциях замены цвета просто подставлять эту переменную. То же самое можно проделать и с переменной text2. Только нужно не забыть заранее определить эти переменные:

var text1, text2; function brws()

{ if (navigator.appName!="Net scape")

{ textl=document.all.textl; text2=document.all.text2 ;

} else { textl=document.getElementById("textl") ;

text2=document.getElementById("text2"); } }

Теперь необходимо сделать так, чтобы нагла функция brws( ) выполнялась сразу после загрузки страницы. Для этого установим в теге <BODY> обработчик событий, реагирующий на загрузку элемента. Он называется onLoad:

<BODY onLoad="brws( )">

Посмотрим, что у нас получается в целом.

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

<HTML>

<HEAD>

<TITLE>06pa6oткa событий мыши (1Е4, NN6)</TITLE>

<SCRIPT LANGUAGE="JavaScript">

var textl, text2; function brws()

{ if (navigator.appName!="Netscape") ( textl=document.all.textl; text2=document.all.text2;

} else { textl=document.getElementById("textl") ; text2=document.getElementById("text2") ;

} } function change () { textl.style.color="red"; text2.style.color="green";

}

function change2() { textl.style.color="black"; text2. style. color="blacl<";

} //-->

</SCRIPT>

</HEAD>

<BODY onLoad="brws()"> Этот текст не изменит свой цвет.

<DIV !D="textl" onMouseOver="change() " onMouseOut="change2()">

Этот текст изменит свой цвет, если

навести на него мышь!

</DIV> <DIV !D="text2">Этот текст изменит свой цвет, если мышь навести на вторую строку!</DIV>

</BODY>

</HTML>

Теперь этот пример работает и в броузере Internet Explorer, и в броузере Netscape 6. Конечно, хотелось бы создавать такие страницы, которые бы работали по крайней мере в этих двух броузерах, потому что в Netscape версии 4 поддержка динамических страниц вообще очень слабая. Однако это не всегда возможно. В этой книге в дальнейшем все примеры будут ориентированы на броузер Internet Explorer версии 4 и выше (если специально не оговорено обратное).

Кнопки, влияющие на вид страницы

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

Для начала в соответствии с требованиями HTML 4.0 заменим атрибуты BGCOLOR= и BACKGROUND= тега <BODY> на соответствующие стилевые свойства:

<STYLE> BODY { background-color: #BFFFBF;

background-image: url("Images/gradi.jpg"); }

</STYLE>

Что же касается тега <BODY>, то ему желательно присвоить имя для облегчения доступа к его свойствам:

<BODY ID="doc">

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

<DIV ALIGN="center"> <INPUT TYPE="button" VALUE="Убрать фоновый рисунок">

<INPUT TYPE="button" VALUE="Сделать фон белым"> </DIV>

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

function noBg() { document.all.doc.style.backgroundlmage='none'; }

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

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

<INPUT TYPE="button" VALUE="y6paть фоновый рисунок" onClick="noBg ()">

Аналогично создадим функцию для смены цвета фона на белый:

function colChangeO ( document.all.doc.stylе.backgroundColor='white'; } и добавим ко второй кнопке обработчик события onClick:

<INPUT TYPE="button" VALUE="Cделать фон белым" onClick="colChange()">

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

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

<INPUT TYPE="button" NAME="buttl" VALUE="Убрать фоновый рисунок" onClick="noBg()">

<INPUT TYPE="button" NAME="butt2"VALUE="Сделать фон белым" onClick="colChange()">

Можно было, разумеется, использовать и атрибут ID= вместо NAME=. Для того чтобы изменить надпись на первой кнопке, достаточно изменить значение ее атрибута VALUE=:

document.all.butti.value='Вернуть фоновый рисунок';

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

function noBg() { if (document.all.doc.style.backgroundlmage="none") { document.all.doc.style.backgroundlmage='none' ;

document.all.butti.value='Вернуть фоновый рисунок';

} else { document.all.doc.style.backgroundlmage="url('Images/gradi.jpg')"'; document.all.butti.values'Убрать фоновый рисунок'; } }

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

Таким же способом мы переделываем функцию colChange(). Сначала проверим значение свойства backgroundColor, и, если оно не совпадает со значением white (белый), присвоим ему это значение, а в противном случае присвоим первоначальное значение #BFFFBF. Одновременно будем изме нять и надпись на второй кнопке: function colChange() { it (document.all.doc.style.backgroundColor!='white'){ document.all.doc.style.backgroundColor"'white' ;

document.all.butt2.value='Сделать фон зеленым';

}

else { document.all.doc.style.backgroundColor='#BFFFBF' ; document.all.butt2,value='Сделать фон белым'; } } Теперь пользователь может с помощью первой кнопки включать и вык- лючать фоновый рисунок по желанию, а с помощью второй — переклю чать цвет фона с зеленоватого на белый и обратно. Однако остался еще один нерешенный вопрос. Дело в том, что если включен фоновый рису- нок, то переключение цвета фона не дает никакого видимого результат”, что может смутить пользователя. Поэтому, пока включен фоновый рису нок, лучше вообще не давать возможности нажимать на вторую кнопку. Internet Explorer позволяет сделать ее недоступной с помощью атрибут DISABLED. Поскольку изначально фоновый рисунок включен, установим этот атрибут сразу же при создании второй кнопки:

<INPUT TYPE="button" NAME="butt2" VALUE="Сделать фон белым" DISABLED onClick="colChange()">

А в функцию noBg( ) следует включить сброс атрибута DISABLED для второй кнопки при выключении фонового рисунка и, соответственно, уста новку этого атрибута при включении фона:

function noBg() { if (document.all.doc.style.backgroundlmage!="none") {

document.all.doc.style.backgroundlmage='none'; document.all.butti.value='Вернуть фоновый рисунок'; document.all.butt2.disabled=false; } else { document.a 11.doc.style.backgroundlmage="url('Images/gradi.jpg')"; document.all.butti.value='Убрать фоновый рисунок'; document.all.butt2.disabled=true; } }

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

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 TRANSITIONAL//EN"> <HTML> <HEAD> <TITLE>CKА3KА</TITLE> <STYLE> BODY { background-color: #BFFFBF; background-image: url("Images/gradi.jpg") ; } </STYLE> <SCRIPT> <!--function noBg() { if (document.all.doc.style.backgroundlmage!="none") { document.all.doc.style,backgroundlmage='none' ; document.all.butti.value='Вернуть фоновый рисунок'; document.all.butt2.disabled=false; } else {

document.all.doc.style.backgroundlmage= "url('Images/gradl.jpg')";

document, all .buttl .value='Убрать фоновый рисунок'; document.all.butt2.disabled=true;

} }

function colChangef)

{ if (document.all.doc.style.backgroundColor!='white')

{ document.all.doc.style.backgroundColor='white' ;

document.all.butt2.value='Сделать фон зеленым'; }

else { document.all.doc.style.backgroundColor='#BFFFBF'' document.all.butt2.value='Сделать фон белым';

}

}

//-->

</SCRIPT>

</HEAD>

<BODY ID="doc"> <DIV ALIGN="center">

<INPUT TYPE="button" NAME-"buttl" VALUE="y6paть фоновый рисунок" onClick="noBg()">

<INPUT TYPE="button" NAME-"butt2 VALUE="Сделать фон белым" DISABLED onClick="colChange()">

</DIV>

<BR>

<DIV ALIGN="center">

<IMG SRC="Images/hr2.gif" WIDTH="508" HEIGHT="18" BORDER="0" ALT""></DIV>

<DIV ALIGN="center">

<IMG SRC="Images/skazk.gif" WIDTH="359" HEIGHT="150" BORDER="0" ALT="CKA3KA"><BR>

<H2> О ТОМ, КАК ИВАН-ДУРАК ПОСРАМИЛ ЦАРЯ ГOPOXA</H2></DIV>

<DIV ALIGN="justify"><IMG SRC="Images/bukvical.gif" WIDTH="121" HEIGHT="111" BORDER="0" ALIGN="LEFT" ALT="Д">

авным-давно жил-был на белом свете царь Горох. И были у него поля гороховые, и леса гороховые, и степи гороховые, и даже моря гороховые. Все было гороховым. И была у него дочь &mdash; царевна Горошина. Волосы у нее были зеленые, и глаза тоже зеленые, потому что с детства только на горох и смотрела. Но вообще-то она была писаной красавицей. Все придворные царские, и бояре, и пажи, и лакеи, и даже слуги и повара дворцовые были по уши влюблены в нее. Но была у царевны Горошины одна странность &mdash; любила она смотреть по ночам на далекую звезду Адырлетавру, которая светила в том царстве так ярко, что обычные люди на той стороне, где звезда была, даже окон в домах не делали. <BR><BR>

<FONT SIZE="+3">............................................

</FONT><BR><BR>

Тут и сказке конец, а кто слушал &mdash; молодец, ему пряник в награду и кило мармеладу.<BR>&nbsp;</DIV>

<DIV ALIGN="center"><IMG SRC=" Images/hr2 .gif" WIDTH="508" HEIGHT="18" BORDER="0" ALT=""></DIV>

</BODY>

</HTML>

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

Заметим, что приведенная выше страница будет работать только в Internet Explorer. Ее можно заставить работать и в Netscape 6 тем же способом, который мы применили в предыдущем примере — путем написания функции, присваивающей одной и той же переменной либо значение document.all, либо document.getElementByld, в зависимости от типа броузера:

var doc, butti, butt2; function brws(),

{ if (navigator.appName!""Netscape") ( buttl=dofc.ument .all. butti; butt2=docwnent.all.butt2; doc=docunysnt. all. doc;

}

else (

buttl=document.getElementById("buttl") ;

butt2=document.getElementById("butt2") ;

doc=document.getElementById("doc") ;

} }

Затем следует переписать функции noBg() и colChange( ), убрав из них обра щение document.all:

function noBg() { if (doc.style.backgroundlmage!="none")

{ doc.style.backgroundlmage='none' ; butti,value='Вернуть фоновый рисунок'; butt2.disabled=false;

} else {

doc.style.backgroundlmage="url('Images/gradi.jpg')";

butti.value='Убрать фоновый рисунок'; butt2.disabled=true;

 

}

function colChange()

{ if (doc.style.backgroundColor!='white')

{ doc.style.backgroundColor='white' ; butt2.value='Сделать фон зеленым';

} else { doc.style.backgroundColor='#BFFFBF' ;

butt2.value='Сделать фон белым'; } }

И, наконец, назначить выполнение функции brws() сразу после загрузки страницы:

<BODY ID="doc" onLoad="brws()">

Теперь наш код будет одинаково работать и в Internet Explorer 4+, и в Netscape 6. Что касается Netscape 4, то, если постараться, можно заставить эту стра ницу работать и там, но это будет довольно сложно. В Netscape 4 нельзя получить доступ непосредственно к свойствам тега <BODY>, однако броузер можно “обмануть”, использовав либо тег <LAYER> и коллекцию document.layers, либо свойства типа document.body.bgColor. Давайте лучше не будем этим заниматься, тем более что смотреть нашу страницу в Netscape 4 все равно можно, просто обе наши кнопки в нем вообще не отобразятся (этот броу зер не воспринимает теги <INPUT> вне элемента <FORM>).

Реализация операций перетаскиванием

Итак, мы рассмотрели несколько основных обработчиков событий. Однако существуют и другие события мыши. Например, веб-страница может отдельно реагировать на нажатие кнопки мыши, на ее отпускание и даже на ее движение. Для чего это может понадобиться? Одно из возможных применений — это реализация так называемой технологии drag-and-drop, (проще говоря — перетаскивания экранных объектов с помощью мыши. Для иллюстрации рассмотрим несложный пример.

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

<STYLE> BODY { . background-color: #979797; color: #FEFEFE; text-align: center;

font-weight: bold; font-size: 30рх;

font-family: sans-serif; . } </STYLE>

затем вывести на экран заголовок; потом создать центрированный блок (<DIV>) с фиксированной шириной и высотой, а также небольшим отсту- пом сверху, заданным с помощью стилевого свойства margin-top:

<DIV ALIGN="center" STYLE="width: 400px; height: 400px; margin-top: 25px;">

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

<TABLE BGCOLOR="#COCOCO" WIDTH="100%" CELLSPACING="0" CELLPADDING="0" BORDER="1">

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

<TD WIDTH="25%" ID="cl"><IMG SRC="Images/digitl.gif" WIDTH="100" HEIGHT="100" BORDER="0" ALT="1"></TD>

Вообще говоря, поскольку ширина (и высота) рисунков определены в 100 пикселов, атрибут WIDTH= указывать для тега <TD> совсем не обязательно. Что же касается атрибута ID=, то мы здесь указали его с расчетом на то, что плашки придется переставлять, и тогда потребуется доступ к ячейкам таблицы.

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

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

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

И, в-третьих, при отпускании кнопки мыши нужно оставить рисунок на том месте, куда он был передвинут.

 

автор: Народный мастер
сайт:  
мыло: kariera2001vit@mail.ru

 

 

вверх

Динамическое управление позиционированием элементов

Чтобы все это реализовать, придется использовать позиционирование объектов на экране. Прежде всего, определим позицию блока, в который будет включена таблица (“игровое поле”):

<DIV STYLE="width: 400px; height: 400px; position: absolute;

top: 100px;">

Вероятно, вы обратили внимание на то, что сейчас мы задали только пози- цию блока <DIV> по вертикали (с помощью стилевого свойства top). А каким должно быть свойство left (позиция по горизонтали)? Хотелось бы, чтобы наше игровое поле располагалось по центру, но ведь мы не знаем ширину окна броузера пользователя!

К счастью, в Internet Explorer есть возможность определить ширину окна броузера, прочитав значение свойства document.body.clientWidth. После этого все уже просто. Сначала разделим это значение на 2, чтобы получить пози цию в центре экрана. Поскольку наша таблица будет иметь ширину 400 пикселов, для вычисления позиции ее левого края вычтем из позиции центра экрана половину ширины таблицы, то есть 200:

tstart=document.body.clientWidth/2-200;

В данном примере мы присвоили вычисленное значение переменной tstart. Поскольку оно будет неоднократно использоваться в дальнейшем, полезно объявить эту переменную как глобальную (то есть не внутри какой-либо функции, а в самом начале кода JavaScript). Теперь осталось дать имя нашему блоку <DIV>:

<DIV ID="maintab" STYLE="width: 400px; height: 400px; position: absolute; top: 100px;">

и присвоить его свойству left вычисленное значение:

<SCRIPT LANGUAGE”"JavaScript" TYPE="text/javascript">

var tstart; function mainpos()

{ tstart document.body.clientWidth/2-200;

document.all.maintab.style.left=tstart; )

//--> </SCRIPT>

Приведенная выше функция mainposO должна выполняться сразу после загрузки страницы (иначе пользователь увидит таблицу неизвестно где). Поэтому установим в теге <BODY> уже знакомый нам обработчик событий on Load:

<BODY onLoad="mainpos() ">

Вот теперь при загрузке страницы (а точнее, сразу после нее) наш блок <DIV>, содержащий таблицу, будет отцентрирован. Но как быть с ячейками таблицы? Ведь мы знаем, что если даже в тегах <TD> указать ширину и высоту, эти требования будут восприняты броузером лишь как рекомендательные, и на экране просто не отобразится ни одна ячейка. Если же поместить в ячейки неразрывные пробелы, то строки таблицы получатся мизерной высоты.

Что же делать? Есть один прием, который позволяет сделать минимальную ширину и высоту ячейки таблицы такой, какой нужно именно нам, а не такой, какой захочет броузер. Дело в том, что при наличии рисунка в ячейке таблицы броузер обязательно расширит границы ячейки так, чтобы рисунок был виден целиком. Поэтому создадим очень маленький графи ческий файл, содержащий целиком прозрачный рисунок (в нашем примере был использован прозрачный рисунок размером 4х3 пиксела). Рисунок такого маленького размера будет загружаться очень быстро, прак- тически не влияя на скорость загрузки страницы. Однако в соответствующем ему теге <IMG> установим ширину и высоту (с помощью атрибутов WIDTH= и HEIGHT=) такими, какими мы хотим видеть ширину и высоту ячейки таблицы. Таким образом, мы получим как бы пустую ячейку с заданными минимальными размерами!

Вот как можно это сделать в нашем примере:

<TD><IMG SRC="Images/diafanol.gif" WIDTH="100" HEIGHT="100"</TD>

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

<IMG ID="pl" SRC="Images/digitl.gif" WIDTH="100" HEIGHT="100" BORDER="0" ALT="1" STYLE="position: absolute; top: 120px; left: 10px;">

<IMG ID="p2" SRC="Images/digit2.gif" WIDTH="100" HEIGHT="100" BORDER="0" ALT="2" STYLE="position: absolute; top: 220px; left: 10px;">

<IMG ID="p3" SRC="Images/digit3.gif" WIDTH="100" HEIGHT="100" BORDER="0" ALT="3" STYLE="position: absolute; top: 320px; left: 10px;">

<IMG ID="p4" SRC="Images/digit4.gif" WIDTH="100" HEIGHT="100" BORDER="0" ALT="4" STYLE="pOsition: absolute; top: 420px; left: 10px;">

<IMG ID="p5" SRC°"Images/digit5.gif" WIDTH="100" HEIGHT="100" BORDER="0" ALT="5" STYLE="position: absolute; top: 520px; left: 10px;">

<IMG ID="p6" SRC="Images/digit6.gif" WIDTH="100" HEIGHT="100" BORDER="0" ALT="6" STYLE="position: absolute; top: 120px; left: 30px;">

<IMG ID="p7" SRC="Images/digit7.gif" WIDTH="100" HEIGHT="100" BORDER="0" ALT="7" STYLE="position: .absolute; top: 220px; left: 30px;">

<IMG ID="p8" SRC="Images/digit8.gif" WIDTH="100" HEIGHT="100" t BORDER="0" ALT="8" STYLE="position: absolute; top: 320px; left: 30px;">

<IMG ID="p9" SRC="Images/digit9.gif" WIDTH="100" HEIGHT="100" BORDER="0" ALT="9" STYLE="position: absolute; top: 420px; left: 30px;">

<IMG ID="plO" SRC="Images/digitl0.gif" WIDTH="100" HEIGHT="100" BORDER="0" ALT="10" STYLE="position: absolute; top: 520px; left: 30px;">

<IMG ID="pll" SRC="Images/digitll.gif" WIDTH="100" HEIGHT="100" BORDER="0" ALT="11" STYLE="position: absolute; top: 120px; left: 50px;">

<IMG ID="pl2" SRC="Images/digitl2.gif" WIDTH="100" HEIGHT="100" BORDER="0" ALT="12" STYLE="position: absolute; top: 220px; left: 50RX;">

<IMG ID="pl3" SRC="Images/digitl3.gif" WIDTH="100" HEIGHT="100" BORDER="0"'\ALT="13" STYLE="position: absolute; top: 320px; left: 50rix;">

<IMG ID="bl4" SRC="Images/digitl4.gif" WIDTH="100" HEIGHT="100" BORDER="01- ALT="14" STYLE="position: absolute; top: 420px; left: 50px;">

<IMG ID="pl5" SRC="Images/digitl5.gif" WIDTH="100" HEIGHT="100" BORDER="0" ALT="15" STYLE="position: absolute; top: 520px; left: 50px;">

Результат показан на рис. 7.9. Пока это выглядит не очень красиво, поскольку на виду у пользователя оказался третий ряд плашек (с цифрами от 11 до 15), а остальные расположились под ним. Лучше было бы, если бы наверху оказались плашки с 1 по 5.

Можно, конечно, решить эту проблему, присвоив каждой плашке свое значение стилевого свойства z-index, однако проще изменить порядок сле дования тегов <IMG>. Если сначала написать теги для рисунков плашек с 11 по 15, затем — с 6 по 10 и в конце — с 1 по 5, то при наложении рисун ков те, которые были объявлены позже, окажутся сверху. Кроме того, вполне можно разместить рисунки чуть выше по вертикали:

<IMG ID="pll" SRC="Images/digitll.gif" WIDTH="100" HEIGHT="100" BORDER="0" ALT="11" STYLE="position: absolute; top: 60px; left: 50px;">

<IMG ID="pl2" SRC="Iniages/digitl2.gif" WIDTH="100" HEIGHT="100" BORDER="0" ALT="12" STYLE="position: absolute; top: 160px; left: 50px;">

<IMG ID="pl3" SRC="Images/digitl3.gif" WIDTH="100" HEIGHT="100" BORDER="0" ALT="13" STYLE="position: absolute; top: 260px; left: 50px;">

<IMG ID="pl4" SRC="Images/digitl,4.gif" WIDTH="100" HEIGHT="100" BORDER="0" ALT="14" STYLE="position: absolute; top: 360рх; left: 50px;">

<IMG ID="pl5" SRC="Images/digitl5.gif" WIDTH="100" HEIGHT="100" BORDER="0" ALT="15" STYLE="position: absolute; top: 460px; left: 50px;">

<IMG ID="p6" SRC="Images/digit6.gif" WIDTH="100" HEIGHT="100" BORDER="0" ALT="6" STYLE="position: absolute; top: 60px; left: 30px;">

<IMG ID="p7" SRC="Images/digit7.gif" WIDTH="100" HEIGHT="100" BORDER="0" ALT="7" STYLE="position: absolute; top: 160px; left: 30px;">

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

Реакция на нажатие кнопки

Сначала добавим в тег <BODY> обработчики событий, реагирующие на нажатие кнопки мыши (не на щелчок, который состоит из нажатия и отпускания левой кнопки, а именно на нажатие) — onMouseDown, на отпускание кнопки — onMouseUp и на движение указателя мыши — onMouseMove:

<BODY onLoad="mainpos()" onMouseDown="down_it()" onMouseUp="up_it()" onMouseMove="move_it()">

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

Прежде всего, нам надо определить, была ли нажата кнопка мыши на рисунке одной из плашек. Если нет, то ничего делать не нужно. Как проверить это условие? В Internet Explorer 4+ источник каждого события записывается в свойство window.event.srcElement. Но что нам это дает? Ведь нужных нам рисунков целых 15, и у каждого есть свое уникальное имя (свойство ID=). Неужели придется сравнивать свойство window.event.srcElement id с каждым именем?

Мы совсем забыли, что каждый рисунок плашки представляет собой тег <IMG>. Поэтому мы можем сравнить свойство window.event.srcElement.tagName, содержащее названия тега-источника события, со словом IMG, и в случае удачи перейти к дальнейшим действиям:

function down_it() { if(window.event.srcElement.tagName=="IMG") { // какие-то действия } } Стоп! Но ведь, кроме рисунков плашек, у нас еще есть прозрачный рисунок, расположенный в каждой из шестнадцати ячеек таблицы! А вот его-то нам никуда передвигать совсем не нужно. При этом от рисунков плашек его отличает только свойство SRC=. Придется сравнить это свойство со значением Images/diafanol.gif, и продолжать дальнейшую работу функции лишь в том случае, если совпадение не обнаружится.

Однако если мы напишем:

if ( (window, event. srcElement. tagNames""IMG") && (window.event.srcElement.src!="Images/diafanol.gif")) {

// какие-то действия }

то в большинстве случаев нас постигнет разочарование: “какие-то действия” все равно будут выполняться, даже если кнопка мыши будет нажата на прозрачном рисунке! В чем же дело?

Оказывается, свойство window.event.srcElement.src в любом случае содержит указание на абсолютное местоположение файла рисунка. Так, например, если эти опыты мы проводим на локальном компьютере, то значением window.event.srcElement.src будет полный путь доступа к файлу, включающий имя диска и родительские папки. Поскольку при разработке страницы, скорее всего, еще нельзя точно предсказать этот путь доступа, да и проверить работу страницы на локальном компьютере тоже нелишне, придется поступить по другому. Воспользуемся тем, что каково бы ни было абсолютное расположение файла, значение window.event.srcElement.src все равно будет заканчиваться его именем — в нашем случае diafanol .gif. то есть символы с 13-го по 5-й от конца строки будут заведомо содержать значение diafanol. Поскольку длина любой строки всегда содержится в ее свойстве length, то мы можем выделить из полного названия файла нужные нам символы, начиная от length-12 и кончая length-4. Выделение части строки можно произвести методом substring:

if((window.event.srcElement.tagName=="IMG")&& (window.event.srcElement.src.substring (window.event.srcElement.src.length-12, window.event.srcElement.src.length-4)!="diafanol")) {

// какие-то действия }

Вот теперь все заработает правильно. Правда, строка условия выглядит очень громоздко. Мы не рекомендуем писать такие строки, поскольку через какое-то время с ними будет трудно разбираться, если вдруг понадобится что-то изменить. Например, в нашем случае можно определить локаль ную переменную 1 и присвоить ей значение window.event.srcElement.src.length. Тогда строка условия будет выглядеть хоть немного компактней:

if((window.eventssrcElement.tagName="IMG") && (window, event .'SrcElement. src.substring (1-12,1-4) != "diafanol"”

Какие же действия нужно осуществить внутри этой функции? Если вы еще не забыли, нам нужно “привязать” рисунок плашки к указателю мыши. Для этого достаточно определить глобальную переменную (мы назвали ее moving), и присваивать ей всегда имя рисунка, который необхо димо передвигать. Если никакой рисунок передвигать не нужно (кнопка мыши отпущена или нажата не на рисунке плашки), можно присвоить переменной moving значение " " (пустая строка). В самом начале сценария эту переменную можно объявить так:

var moving"";

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

moving=window.event.srcElement.id;

Реакция на перемещение мыши

В принципе, наша функция down_it() уже справляется со своими обязанностями. Теперь давайте займемся функцией moveit( ), которая будет вызываться при движении мыши.

Эта функция должна прежде всего проверить, нужно ли передвигать какой- либо рисунок. Как вы помните, его имя содержится в переменной moving. Так что нужно сначала сравнить значение переменной moving с пустой стро кой и в случае совпадения не предпринимать никаких действий:

function move it() { if (moving!="") { // какие-то действия

} }

Теперь давайте подумаем, что должно быть сделано, если переменная moving содержит имя рисунка, который нужно передвинуть. Очевидно, для того чтобы его передвинуть, нужно изменить его стилевые свойства left и top в соответствии с расположением указателя мыши. Текущее положение указателя мыши можно узнать, прочитав значения свойств window.event.clientX и window.event.clientY.

— Стоп! — скажете вы. — А как узнать, как должен располагаться рису нок относительно указателя мыши? Ведь пользователь может щелкнуть и в центре рисунка, и с краю, и в любом другом месте. Значит, в функции down_it(), которую мы считали уже законченной, нужно еще вычислить координаты указателя мыши относительно рисунка?

— Правильно! Это обязательно нужно сделать, если применять эту технологию для перетаскивания крупных объектов. Но в нашем примере мы позволим себе упростить задачу, воспользовавшись тем, что наши плашки имеют относительно небольшие размеры. При таких размерах будет вполне нормально, если при перетягивании рисунка указатель мыши будет находиться посередине его. Поскольку рисунки наши имеют размер 100х100, нам остается вычесть 50 из каждой координаты указателя мыши и при своить эти значения свойствам left и top рисунка:

document.all[moving].style.pixelLeft=window.event.clientX-50; document.all[moving].style,pixelTop=window.event.clientY-50;

Обратите внимание на то, что для обращения к объекту по его имени, содержащемуся в переменной, необходимо использовать квадратные скобки, то есть писать document.all[moving], а не document.all. moving. В противном случае броузер не сможет найти нужный объект и выдаст сообщение об ошибке . Кроме того, обратите внимание на то, что для корректного изменения координат в Internet Explorer необходимо использовать свойства pixelLeft и pixelTop вместо left и top.

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

window.event.cancelBubble = true; window.event.returnValue = false;

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

window.event.returnValue = false;

тo рисунки начнут “тормозиться” уже при небольшом перемещении, после чего броузер может вообще не распознать отпускание кнопки мыши. Мы сейчас не будем вдаваться в подробности того, почему так происходит. Однако запомните, что эти две короткие строчки при обработке событий мыши часто помогают избежать многих неприятностей. Если у вас что-то не получается, проверьте, а не “всплывает” ли какое-нибудь нежелательное событие? И не пытается ли броузер делать что-то “свое” вместо назначенных вами операций?

Реакция на отпускание кнопки

Теперь давайте займемся функцией up_it(), выполняющейся при отпускании кнопки мыши. Собственно говоря, все, что нужно сделать — это проверить, передвигался ли какой-нибудь объект (то есть, содержит ли переменная moving какое-либо имя) и, если это так, присвоить этой переменной пустую строку, что будет означать “освобождение” рисунка: function up_it() ( if (moving!="") moving="";

Однако хорошо бы еще расположить рисунок не где попало, а точно в ячейке таблицы. Поскольку в этом случае его координаты относительно начала таблицы должны быть кратны 100, это довольно легко осуществить. Для этoгo достаточно округлить его до ближайшей сотни. Для округления можно использовать встроенный метод Math.round. Понятно, что он округляет не до сотен, а до целых чисел, поэтому текущие координаты рисунка перед округлением придется разделить на 100, а после округления — умно жить на 100. Кроме того, не забывайте, что кратность 100 мы определяем относительно начала таблицы, которое равно tstart по горизонтали и 100 но вертикали. Поэтому перед делением на 100 нужно еще вычесть из горизонтальной координаты значение tstart, а в конце снова его прибавить. Вот что у нас получается:

document.all[moving].style.pixelLeft= Math.round;(window.event.clientX-50-tstart)/100)*100+tstart+l;

document.all[moving].style,pixelTop= Math.round((window.event.clientY-50)/100)*100+1;

Как видите, все довольно просто. Здесь мы прибавили к каждой коорди нате еще по единице, чтобы рисунки не налезали на сетку таблицы. Кстати, ширину ячеек таблицы (то есть, прозрачного рисунка diafanol.gif) в этом случае тоже необходимо немного скорректировать. Поскольку каждая ячейка таблицы имеет со всех сторон бордюр шириной в 1 пиксел, придется сделать ширину самих ячеек равной не 100, а 98:

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

if (window.event.clientX>=tstart-50&&window.event,clientY>=50) {

document.all[moving].style.pixelLeft= Math.round((window.event.clientX-50-tstart)/100)*100+tstart+l;

document.all[moving].style,pixelTop= Math.round((window.event.clientY-50)/100)* 100+1;

}

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

document.all[moving].style.zlndex=5;

Поскольку у всех остальных элементов значение z-index не изменялось (и, следовательно, равно нулю), мы добиваемся того, что перемещаемый рисунок никогда не будет перекрыт другими объектами. Естественно, при окончании перемещения рисунка ему нужно возвратить исходное значение z-index. Для этого в функцию up_it() добавим строку

document.a 11[moving].style.zlndex=0; Итак, давайте посмотрим, что же у нас получается.

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

<HTML>

<HEAD>

<TITLE>Иrpa 15</TITLE>

<STYLE> BODY { background-color: #979797; color: #FEFEFE;

text-align: center; font-weight: bold;

font-size: 30рх; font-family: sans-serif; }

</STYLE>

<SCRIPT LANGUAGE="JavaScript" TYPE="text/javascript">

var tstart; var moving="";

function mainpbs( )

{ tstart=document.body.clientWidth/2-200;

document. a.is .rnaintab. style. left=tstart;

function down_it()

{ var 1==window. event. srcElement. src.length;

if((window.event.srcElement.tagName="IMG")&&

(window.event.srcElement.src.substring(1-12,1-4)!= "diafanol"))

{ moving=window.event.srcElement.id;

document.all[moving].style.pixelLeft=window.event.clientX-50; document.all[moving].style.pixelTop=window.event.clientY-50;

document.all[moving].style.zlndex=5; } } function up it() { if (moving!="") {

if (window.event.clientX>=tstart-50&& window.event.clientY>=50) {

document.all[moving].style.pixelLeft= Math.roundf(window.event.clientX-50-tstart)/100)*100+tstart+1;

document.all[moving].style,pixelTop= Math.round((window.event.clientY-50)/100)*100+1;

} document.all[moving].style.zlndex=0; moving=""; }

} function move it() { if (moving!="")

{ document.all[moving].style.pixelLeft=window.event.clientX-50; document.all[moving].style.pixelTop==window.event.clientY-50 ;

} event.cancelBubble = true; event.returnValue = false; }

//—>

</SCRIPT>

</HEAD>

<BODY enLoad="mainpos()" опМouseDown="down it()" onMouseUp="up_it()" onMouseMove="move_it()">

Расставьте плашки перетаскиванием с помощью мыши

<DIV ID="maintab" STYLE="width: 400px; height: 400px; position: absolute; top: 100px;">

<TABLE BGCOLOR="#COCOCO" WIDTH="100%" CELLSPACING="0" CELLPADDING="0" BORDER="1">

<TR>

<TD><IMG SRC="Images/diafanol.gif" WIDTH="98" HEIGHT="98"></TD>

<TD><IMG SRC="Images/diafanol.gif" WIDTH="98" HEIGHT="98"></TD>

<TD><IMG SRC="Images/diafanol.gif" WIDTH="98" HEIGHT="98"></TD>

<TD><IMG SRC="Images/diafanol.gif" WIDTH="98" HEIGHT="98"></TD> </TR> <TR>

<TD><IMG SRC="Images/diafanol.gif" WIDTH="98" HEIGHT="98"></TD>

<TD><IMG SRC="Images/diafanol.gif" WIDTH="98" HEIGHT="98"></TD>

<TD><IMG SRC="Images/diafanol.gif" WIDTH="98" HEIGHT="98"></TD>

<TD><IMG SRC="Images/diafanol.gif" WIDTH="98" HEIGHT="98"></TD> </TR> <TR>

<TD><IMG SRC="Images/diafanol.gif" WIDTH="98" HEIGHT="98"></TD>

<TD><IMG SRC="Images/diafanol.gif" WIDTH="98" HEIGHT="98"></TD>

<TD><IMG SRC="Images/diafanol.gif" WIDTH="98" HEIGHT="98"></TD>

<TD><IMG SRC="Images/diafanol.gif" WIDTH="98" HEIGHT="98"></TD> </TR> <TR>

<TD><IMG SRC="Images/diafanol.gif" HIDTH="98" HEIGHT="98"></TD>

<TD><IMG SRC="Images/diafanol.gif" WIDTH="98" HEIGHT="98"></TD>

<TD><IMG SRC="Images/diafanol.gif" WIDTH="98" HEIGHT="98"></TD>

<TD><IMG SRC="Images/diafanol.gif" WIDTH="98" HEIGHT="98"></TD>

</TR> </TABLE> </DIV>

<IМG ID="p11" SRC="Images/digitll.gif" WIDTH="100" HEIGHT="100" BORDER="0" ALT="11" STYLE="position: absolute; top: 60px; left: 50px;

<IMG ID="pl2 SRC="Images/digitl2.gif" WIDTH="100" HEIGHT="100" BORDER="0" AtlT="12" STYLE="position: absolute; top: 160px; left: 50px;

<IMG ID="p13 SRC-"Images/digitl3.gif" WIDTH="100" HEIGHT="100" BORDER="0" ALT="13" STYLE="position: absolute; top: 260px; left: 50px;">

<IMG ID="pl4" SRC="Images/digitl4.gif" WIDTH="100" HEIGHT="100" BORDER="0" ALT="14" STYLE="position: absolute; top: 36Орх; left: 50px;">

<IMG ID="pl5" SRC="mages/digitl5.gif" WIDTH="100" HEIGHT="100" BORDER="0" ALT="15" STYLE="position: absolute; top: 460px; left: 50px;">

<IMG ID="p6" SRC="Images/digit6.gif" WIDTH="100" HEIGHT="100" BORDER="0" ALT="6" STYLE="position: absolute; top: 60px; left: 30px;">

<IMG ID="p7" SRC="Images/digit7.gif" WIDTH="100" HEIGHT="100" BORDER="0" ALT="7" STYLE="position: absolute; top: 160px; left: 30px;">

<IMG ID="p8" SRC="Images/digit8.gif" WIDTH="100" HEIGHT="100" BORDER="0" ALT="8" STYLE="position: absolute; top: 260px; left: 30px;">

<IMG ID="p9" SRC="Images/digit9.gif" WIDTH="100" HEIGHT="100" BORDER="0" ALT="9" STYLE="position: absolute; top: ЗбОрх; left: 30px;">

<IMG ID="plO" SRC="Images/digitl0.gif" WIDTH="100" HEIGHT="100" BORDER="0" ALT="10" STYLE="position: absolute; top: 460px; left: 30px;">

<IMG ID="pl" SRC="Images/digitl.gif" WIDTH="100" HEIGHT="100" BORDER="0" ALT="1" STYLE="position: absolute; top: 60px; left: 10px;">

<IMG ID="p2" SRC="Images/digit2.gif" WIDTH="100" HEIGHT="100" BORDER="0" ALT="2" STYLE="position: absolute; top: 160px; left: 10px;">

<IMG ID="p3" SRC="Images/digit3.gif" WIDTH="100" HEIGHT="100" BORDER="0" ALT="3" STYLE="position: absolute; top: 260px; left: 10px;">

<IMG ID="p4" SRC="Images/digit4.gif" WIDTH="100" KEIGHT="100" BORDER="0" ALT="4" STYLE="position: absolute; top: ЗбОрх; left: 10px;">

<IMG ID="p5" SRC="Images/digit5.gif" WIDTH="100" HEIGHT="100" BORDER="0" ALT="5" STYLE="position: absolute; top: 460px; left: 10px;">

</BODY>

</HTML>

Результат представлен на рис. 7.11. В принципе, в такую игру уже можно по-настоящему играть. Конечно, этот код можно еще упростить. Правильно, зачем шестнадцать раз повторять тег вставки прозрачного рисунка? Давайте заменим его вложенным циклом JavaScript:

for (var k=l; k<=4; k++) { document.write("<TR>") ;

for (var m=l; m<=4; m++) document.write('<TD> <IMG SRC="Images/diafanol.gif" WIDTH="98" HEIGHT="98"> </TD>') ;

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

}

Результат будет тот же. А если немного подумать, то можно сократить даже код первоначального расположения рисунков плашек, правда, это немного труднее.

Кроме того пока что мы никак не проверяем, не ставит ли пользователь две плaшки в одну и ту же ячейку, а уж о самой игре и говорить нечего. Но ведь мы пока только реализовывали расстановку плашек методом перетаскивания. Запомните рассмотренные в этом разделе приемы, так как они позволяют организовать столь любимую пользователями интерактивность просто на небывалом уровне — вспомните, что одна из функций реагировала у нас буквально на каждое перемещение указателя мыши!

К сожалению, приведенная выше страница будет работать только в Internet Explorer. Если необходимо, чтобы она работала также и в Netscape 6, придется приложить некоторые усилия. Дело в том, что помимо различий в син таксисе доступа к элементам, о котором мы уже говорили (в Netscape используется конструкция document.getElementByld вместо document.all), различия существуют также и в обработке событий. В частности, вместо глобального объекта event в Netscape необходимо использовать временную переменную, которой будет передаваться значение объекта event. Кроме того, вместо свойства srcElement используется свойство target, а свойство returnValue вообще не поддерживается. Выше мы приводили примеры того, как написать код, работающий в обоих популярных броузерах. Вы можете в качестве упраж нения попробовать это сделать и для данного примера, однако из-за обработки событий мыши это будет сложнее, чем в предыдущих случаях.

 

автор: Народный мастер
сайт:  
мыло: kariera2001vit@mail.ru

 

 

вверх

7.3. Страница, управляемая с клавиатуры

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

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

Реакция на нажатие клавиши

Давайте попробуем реализовать эту возможность. Для начала назначим элементу <BODY> обработчик событий, реагирующий на нажатие клавиш. Он называется onKeyPress:

<BODY onKeyPress="press()">

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

Обратите внимание на то, что для организации доступа к каждой букве (и к началу файла) нам не придется прикладывать никаких дополнительных усилий! Ведь мы уже ранее создали соответствующие якоря с помо щью тега <А>, и хотя они и не имеют атрибута ID=, у них есть атрибут NAME=, который тоже можно использовать для доступа к элементам.

Итак, при нажатии на клавишу нужно проверить, какая буква была нажата. Это можно сделать, прочитав значение свойства window event keyCode. Оно равно ASCIIJ-коду нажатой клавиши. Например, если нажата клавиша с русской буквой а, то значение свойства window event keyCode равно 1072, то есть коду этой буквы.

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

switch(window.event.keyCode) { case 1072: // какие-то действия case 1073: // какие-то действия и т.д.

Чтобы прокрутить страницу к заданному элементу, можно воспользоваться методом scrolllntoView( ). Например, если мы напишем

document.all.BukvaA.scrolllntoView() ;

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

Учет раскладки клавиатуры

Теперь надо подумать еще о том, что пользователь может забыть переклю- читься на русскую раскладку клавиатуры. Давайте не будем заставлять его это делать. Поскольку мы знаем, что на одной клавише с русской бук вой а расположена буква f, на одной клавише с б — знак < и т. д., мы можем осуществить проверку не только кодов букв а, б, в, г, д, е, но и кодов сим волов f, <, d, u, I, t. Можно написать, например, так: case 1072: case 102: document.all.BukvaA.scrolllntoViewO; break; case 1073: case 44: document.all.BukvaB.scrollIntoView() ; break;

В этом случае прокрутка к букве а осуществится, даже если пользователь нажмет клавишу с буквой а или f, забыв переключиться на русскую рас-кладку клавиатуры. Аналогично можно осуществить прокрутку и к дру- им буквам. Чтобы при нажатии какой-нибудь иной клавиши вернуться началу файла, можно присвоить это возвращение случаю “default”:

default”: document.all.Top.scrollIntoView(); break;

Вот, собственно говоря, и все. Но чтобы изучить еще некоторые обработчики событий, давайте добавим еще эффект уменьшения яркости текста во время нажатия клавиши. Так обращают внимание пользователя на то, что “что-то происходит” (а именно: прокрутка). Для этого нужно использо-вать обработчики событий, реагирующие раздельно на нажатие и на отпускание клавиши. Они называются, соответственно: onKeyDown и onKeyUp:

<BODY onKeyPress="press ()" onKeyDown="this.style.color='gray'" onKeyUp="this style.color='black'">

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

Подсказка для читателя

И в качестве последнего штриха давайте добавим подсказку для пользователя. Пусть, когда он начнет прокручивать страницу вручную (с помощью полосы прокрутки), в строке состояния отобразится такая подсказка: Вы можете перемещаться к нужной букве, используя клавиатуру'. Это можно сделать, используя обработчик событий, реагирующий на прокрутку страницы (есть и такой!). Он называется onScroll:

<BODY onKeyPress="press ()" onKeyDown="this.style.color='gray'" 'Вы можете перемещаться к нужной букве, используя клавиатуру''">

Кстати, один раз появившись, подсказка так и останется в строке состояния, но в данном случае в этом нет ничего плохого. Строка состояния — место не самое заметное, так что подсказка в ней выглядит вполне корректно. Вот чего делать не надо, так это использовать бросающиеся в глаза методы типа alert:

<BODY onKeyPress="press ()" onKeyDown="this.style.color='gray'" onKeyUp="this.style.color='black'" onScroll="void(0); ">

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

Ладно, давайте посмотрим, что у нас получилось, здесь введено еще несколько усовершен ствований, связанных с использованием таблицы стилей. Например, нет необходимости каждый термин заключать в теги <В> и </В>. Вместо этого для тега <DT> заранее определено стилевое свойство font-weight: bold;.

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

<HTML>

<HEAD>

<TITLE>Словарь терминов</ТIТLЕ>

<META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html" CHARSET="windows-1251">

<STYLE> BODY ( background-color: #EAEAEA; color: black;

} A:link, A:active, A:visited { color: #7A3F51;}

DT { font-weight: bold; } </STYLE>

<SCRIPT LANGUAGE="JavaScript" TYPE="text/javascript">

<!--

function press () switch(window.event.keyCode)

{ case 1072: case 102: document.all.BukvaA.scrollIntoView() ;

break; case 1073: case 44: document.all.BukvaB.scrollIntoView() ;

break; case 1074: case 100: document.all.BukvaV.scrollIntoView () ;

break; case 1075: case 117: document.all.BukvaG.scrollIntoView() ;

document.all.BukvaD.scrollIntoView() ;

break; case 1077: case 116: document.all.BukvaE.scrollIntoView() ;

break; default:

document.all.Top.scrollIntoView() ; break;

} }

//-->

</SCRIPT>

</HEAD>

<BODY onKeyPress="press()" onKeyDown="this.style.color='gray'" onKeyUp="this.style.color='black'" onScroll="foo1 = 'Вы можете перемещаться к нужной букве, используя клавиатуру!'">

<Н1><А NAME="Top">Cловарь терминов</А></Н1>

<HR ALIGN="left" WIDTH="40%">

<НЗ> <А HREF="#BukvaA">A</A>

<А HREF="#BukvaB">Б</A> <А HREF="#BukvaV">B</A>

<А HREF="#BukvaG">Г</A> <А HREF="#BukvaD">Д</A>

<А HREF="#BukvaE">E</A> </НЗ> Для перемещения к соответствующей букве вы можете использовать клавиатуру

<HR ALIGN="left" WIDTH="40%">

<Н1><А NAME="BukvaA">A</A></Hl>

<DL> <DT><A NAME="avtentich">AБTEHTИЧECKИЙ КАДАНС</А>

<DD>кадансовый оборот, в котором заключительная тоническая гармония предваряется доминантовой

<DT>

<A NAME="aliquot">AЛИKBOTHЫE СТРУНЫ</А>

<DD>резонирующие струны, к которым исполнитель не прикасается во время игры

<DT><A NAME="atakta">ATAKTA</A>

<DD>гармонический элемент на басу нижнего или верхнего вводного тона

</DL> <SMALLXA HREF="#Top">B начало</А>

</SМАLL> <HR ALIGN="'left" WIDTH="40%">

<H1><A NAME="BukvaB">Б</A></Hl>

<DL> <DT><A NAME="bagatel">БАГАТЕЛЬ</A>

<DD>небольшая нетрудная для исполнения пьеса <DT>

<A NAME="bartok">БAPTOKOBCKOE ПИЦЦИКАТО</А>

<DD>сильный щипок струны с последующим ударом о струны о гриф <DT>

<A NAME="bonang">БОНАНГ</A> <DD>Ha6op из 10-12 гонгов разного размера </DL>

<SMALL><A HREF="#Top">B Haчaлo</A></SMALL>

<HR ALIGN="left" WIDTH="40%">

<H1><A NAME="BukvaV">B</A></Hl> <DL>

</DL> <SMALL>

<A HREF="#Top">B Haчaлo</A></SMALL>

<HR ALIGN="left" WIDTH="40%">

<H1><A NAME="BukvaG">Г</A></Hl>

<DL> </DL> <SMALL><A HREF="#Top">B Haчano</A></SMALL>

<HR ALIGN="left" WIDTH="40%">

<H1><A NAME="BukvaD">Д</A></Hl>

<DL> </DL>

<SMALL><A HREF="#Top">B Haчaлo</A></SMALL>

<HR ALIGN="left" WIDTH="40%">

<H1><A NAME="BukvaE">E</A></Hl>

<DL></DL> <SMALL>

<A HREF="#Top">B начало</A></SMALL>

</BODY>

</HTML>

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

 

автор: Народный мастер
сайт:  
мыло: kariera2001vit@mail.ru

 

 

вверх

design: ФуксЪ 


@ portalus.ru