0  На главную

0 1.Как создают веб-страницы
Как написать веб-страницу
Обзор программ для просмотра
и создания веб-страниц
Создание веб-страниц

0 2.Основные средства языка HTML
Самое главное на любой веб-странице - гиперссылки
Как создать списки на веб-странице
Создание таблиц

0 3.Графика на веб-странице
Графические форматы
интернета
Графические элементы оформления
веб-страниц
Графические маркеры
Подготовка рисунков в
программе Adobe Photoshop

0 4.Оформление веб-страницы с использованием стилей
Определение стилей в
специальной таблице
Обзор других возможностий
стилевых таблиц

0 5.Использование звука на
веб-странице
Маленькие хитрости

0 6.Динамические веб-страницы
на основе JavaScript
Как писать собственные функции
Динамическое изменение внешнего
вида страницы
Другие возможности языка
JavaScript

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

0 8.Размещение элементов на веб-странице
с помощью таблиц
Управление расположением элементов
на веб-страницы
Динамическое позиционирование слоев

0 9.Дополнительные возможности формирования веб-страниц
Пример использования элемента управления Tabular Data

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

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

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

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

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<ТIТLЕ>Обработка событий мыши< /ТIТLE >
</HEAD>
<BODY> Этот текст не изменит свой цвет . Этот текст изменит свой цвет, если навести на него мышь! Этот текст не изменит свой цвет . </BODY>
</HTML>

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

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

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

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

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

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

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

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

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

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

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

При этом лучше использовать полную форму записи доступа через коллекцию document.all, как объяснялось в главе 6:

<DIV ID="text1"'
onMouseOver="document.all.text1.style.color=' red' "
onMouseOut="document.all.text1.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.text1.style.color="black";
document.all.text2.style.color="black";
}

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

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

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

var text1, text2;
function brws() {
if (navigator.appName!="Netscape")
{
text1=document.all.text1;
text2=document.all.text2;
} else {
text1=document.getElementById("textl");
text2=document.getElementById("text2");

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

<BODY onLoad="brws() ">

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

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<ТIТLЕ>Обработка событий мыши (IЕ4, NN6) </TITLE>
<SCRIPT LANGUAGE="JavaScript">
<!--
var text1, text2;
function brws ()
{
if (navigator .appName !="Netscape")
{
text1=document . all . text1 ;
text2=document . all . text2 ;
} else
{
text1=document.getElementById( "text1") ;
text2=document.getElementBy!d("text2") ;
}
}
function change () {
text1.style.color="red";
text2.style.color="green";
function change2() {
text1.style.color="black";
text2.style.color="black";
}
//-- >
</SCRIPT>
</HEAD>
<BODY
onLoad="brws () "> Этот текст не изменит свой цвет.
<DIV ID="text1" onMouseOver="change () " onMouseOut="change2 () ">Этот текст изменит свой цвет, если навести на него мышь ! </DIV>
<DIV ID="text2">Этот текст изменит свой цвет, если мышь навести на вторую строку! </DIV>
</BODY>
</HTML>

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

Рис. 7.5. Страница, на которой цвет строк может изменяться

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

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

Попробуем это реализовать. Возьмем в качестве исходного текст веб-страницы, продемонстрированной на рис. 3.11 в главе 3. Для начала в соответствии с требованиями HTML 4.0 заменим атрибуты BGCOLOR= и BACKGROUND тега <BODY> на соответствующие стилевые свойства:

<STYLE>
BODY {
background-color: #BFFFBF;
background-image: url("Images/grad1.jpg") ;
}
</STYLE>

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

<BODY ID="doc">

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

<DIV ALIGN="center">

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

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

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

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

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

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

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

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

function colChange() {
document.all.doc.style.backgroundColor='white';
}

и добавим ко второй кнопке обработчик события onClick:

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

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

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

<INPUT TYPE="button" NAME="butt1" VALUE="Убрать фоновый рисунок"
onClick="noBg()">
<INPUT TYPE="button" NAME="butt2" VALUE="Сделать фон белым"
onClick="colChange()">

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

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

Рис. 7.6. Веб-страница с кнопками управления фоном

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

function noBg() {
if (document.all.doc.style.backgroundImage!="none")
{document.all.doc.style.backgroundImage='none';
document.all.buttl.value='Вернуть фоновый рисунок';
}else
{
document.all.doc.style.backgroundImage="url(' Images/grad1.jpg')";
document.all.butt1.value='Убрать фоновый рисунок';
}
}

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

Таким же способом мы переделываем функцию colChange(). Сначала проверим значение свойства backgroundColor, и, если оно не совпадает со значением white (белый), присвоим ему это значение, а в противном случае присвоим первоначальное значение #BFFFBF. Одновременно будем изменять и надпись на второй кнопке:

function colChange() {
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='Сделать фон белым';
}
}

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

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

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

function noBg() {
if (document.all.doc.style.backgroundImage!="none") {
document.all.doc.style.backgroundImage='none';
document.all.butt1.value='Вернуть фоновый
рисунок';
document.all.butt2.disabled=false;
}
else {
document.all.doc.style.backgroundImage="url('Images/gradl.jpg')";
document.all.butt1.value='Убрать фоновый рисунок';
document.all.butt2.disabled=true;
}
}

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

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 TRANSITIONAL//EN">
<HTML>
<HEAD>
<TITLE>CKАЗКА</TITLE>
<STYLE> BODY { background-color: #BFFFBF;
background-image: url ("Images/grad1 . jpg") ;
}
</STYLE> <SCRIPT>
<!--
function noBg() {
if (document. all .doc. style. backgroundImage!="none") {
document .all .doc. style .backgroundImage=' none' ;
document .all .butt1.value=' Вернуть фоновый рисунок';
document. all. butt2.disabled=false;
}
else {
document . all . doc . style . backgroundImage= "url (' Images/grad1.jpg' ) ";
document. all. butt1 .value=' Убрать фоновый рисунок';
document. all. butt2.disabled=true;
}
}
function colChange() {
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=' Cделать фон белым';
}
}
//-- >
</SCRIPT>
</HEAD>
<BODY ID="doc">
<DIV ALIGN="center">
<INPUT TYPE="button" NAME="butt1" 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; царевна Горошина. Волосы у нее были зеленые, и глаза тоже зеленые, потому что с детства только на горох и смотрела. Но вообще-то она была писаной красавицей. Все придворные царские, и бояре, и пажи, и лакеи, и даже слуги и повара дворцовые были по уши влюблены в нее . Но была у царевны Горошины одна странность — любила она смотреть по ночам на далекую звезду Адырлетавру, которая светила в том царстве так ярко, что обычные люди на той стороне, где звезда была, даже окон в домах не делали . <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>

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

Рис. 7.7. Веб-страница, на которой «бесполезная» в данный момент кнопка недоступна

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

var doc, butt1, butt2;
function brws() {
if (navigator.appName!="Netscape") {
buttl=document.all.butt1;
butt2=document.all.butt2 ;
doc=document.all.doc ;
}
else {
butt1=document.getElementById("butt1");
butt2=document.getElementById("butt2");
doc=document.getElementById("doc");
}
}

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

function noBg() {
if (doc.style.backgroundImage!="none") {
doc.style.backgroundImage='none';
butt1.value='Вернуть фоновый рисунок';
butt2.disabled=false;
}
else {
doc.style.backgroundImage="url('Images/grad1.jpg')";
butt1.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, проще говоря — перетаскивания экранных объектов с помощью мыши. Для иллюстрации рассмотрим несложный пример.

Предположим, вы хотите проиллюстрировать на своей странице знаменитую игру Лойда «Пятнадцать», например так, как показано на рис. 7.8.Вообще говоря, если вы уже прочитали главы 2, 3 и 4 этой книги, то, скорее всего, сразу сообразите, как можно создать подобную страницу. Нужно, вроде бы, сначала просто задать стиль для текста:

<STYLE> BODY {
background-color: #979797;
color: #FEFEFE;
text-align: center;
font-weight: bold;
font-size:З0рх;
font-family: sans-serif;
} </STYLE>

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

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

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

Рис. 7.8. Страница, иллюстрирующая игру «Пятнадцать»

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

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

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

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

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

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

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

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

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

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

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

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

<BODY onLoad="mainpos()">

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

Рис. 7.9. Указание в тегах <TD> высоты и ширины не приводит к желаемому результату

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

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

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

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

<IMG ID="p1" SRC="Images/digit1.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" 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="р10" SRC="Images/digit10.gif" WIDTH="100" HEIGHT="100" BORDER="0" ALT="10" STYLE="position : absolute; top: 520px; left: 30px;">
<IMG ID="p11" SRC="Images/digit11.gif". WIDTH="100" HEIGHT="100" BORDER="0" ALT="11" STYLE="position: absolute; top: I20px; left: 50px;">
<IMG ID="p12" SRC="Images/digit12.gif" WIDTH="100" HEIGHT="100" BORDER="0" ALT="12" STYLE="position: absolute; top: 220px; left: 50px;">
<IMG ID="p13" SRC="Images/digit13.gif" WIDTH="100" HEIGHT="100" BORDER="0" ALT="13" STYLE="position: absolute; top: 320px; left: 50px;">
<IMG ID="p14" SRC="Images/digit14.gif" WIDTH="100" HEIGHT="100" BORDER="0" ALT="14" STYLE="position: absolute; top: 420px; left: 50px;">
<IMG ID="p15" SRC="Images/digit15.gif" WIDTH="100" HEIGHT="100" BORDER="0" ALT="15" STYLE="position: absolute; top: 520px; left: 50px;">

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

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

<IMG ID="p11" SRC="Images/digit11.gif" WIDTH="100" HEIGHT="100" BORDER="0" ALT="11" STYLE="position: absolute; top: 60px; left: 50px;">
<IMG ID="p12" SRC="Images/digit12.gif" WIDTH="100" HEIGHT="100" BORDER="0" ALT="12" STYLE="position: absolute; top: 160px; left: 50px;">
<IMG ID="p13" SRC="Images/digit13.gif" WIDTH="100" HEIGHT="100" BORDER="0" ALT="13" STYLE="position: absolute; top: 260px; left: 50px;">
<IMG ID="p14" SRC="Images/digit14.gif" WIDTH="100" HEIGHT="100" BORDER="0" ALT="14" STYLE="position: absolute; top: З60рх; left: 50px;">
<IMG ID="p15" SRC="Images/digit15.gif" WIDTH="100" HEIGHT="100" BORDER="0" ALT="15" STYLE="position: absolute; top: 460px; left: 50px;">

Рис. 7.10. Исходная позиция для расстановки плашек

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

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

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

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

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

Рис. 7.11. Изменение порядка следования позиционированных элементов <IMG> позволяет

изменить их расположение в третьем измерении

Теперь осталось написать функции, которые мы так лихо назначили обработчикам событий. Сначала давайте займемся нажатием кнопки мыши (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.tagName=="IMG")&&
(window.event.srcElement.src!="Images/diafanol.gif")) {
// какие-то действия
}

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

Оказывается, свойство window.event.srcElement.src в любом случае содержит указание на абсолютное местоположение файла рисунка. Так, например, если эти опыты мы проводим на локальном компьютере, то значением window.event.srcElement.src будет полный путь доступа к файлу, включающий имя диска и родительские папки. Поскольку при разработке страницы, скорее всего, еще нельзя точно предсказать этот путь доступа, да и проверить работу страницы на локальном компьютере тоже нелишне, придется поступить по другому. Воспользуемся тем, что каково бы ни было абсолютное расположение файла, значение window.event.srcElement.src все равно будет заканчиваться его именем — в нашем случае diafano1 .gif. то есть символы с 13-го по 5-й от конца строки будут заведомо содержать значение diafano1. Поскольку длина любой строки всегда содержится в ее свойстве 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")) {
// какие-то действия
}

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

if((window.event.srcElement.tagName=="IMG")
&&(window.event.srcElement.src.substring(1-12,1-4)!= "diafano1"))

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

var moving=" " ;

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

moving=window.event.srcElement.id;

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

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

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

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

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

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

— Правильно! Это обязательно нужно сделать, если применять эту технологию для перетаскивания крупных объектов. Но в нашем примере мы позволим себе упростить задачу, воспользовавшись тем, что наши плашки имеют относительно небольшие размеры. При таких размерах будет вполне нормально, если при перетягивании рисунка указатель мыши будет находиться посередине его. Поскольку рисунки наши имеют размер 100x100, нам остается вычесть 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 необходимо использовать свойства pixel Left и pixelTop вместо left и top.

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

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

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

window.event.returnValue = false;

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

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

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

function up_it() {
if (moving!="") moving="";
}

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

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

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

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

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

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

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+1;
document.all[moving].style.pixelTop=
Math.round((window.event.clientY-50)/100)*100+1;
}

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

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

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

document.all[moving].style.zIndex=0;

Итак, давайте посмотрим, что же у нас получается.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<TITLE>Игра 15</TITLE>
<STYLE> BODY {
background-color: #979797;
color: #FEFEFE;
text-align: center;
font-weight: bold;
font-size: З0рх;
font-family: sans-serif;
}
</STYLE>
<SCRIPT LANGUAGE=" JavaScript" TYPE="text/javascript">
<!-- var tstart;
var moving="";
function mainpos() {
tstart=document.body.clientWidth/2-200;
document . all .maintab . 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) ! ="diafano1")) {
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. zIndex=5;
}
}
function up_it() {
if (moving !="") {
if (window. event. clientX>=tstart-50&&
window. event. clientY>=50) {
document . all [moving] . style .pixelLeft=
Math. roundt (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. zIndex=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 onLoad="mainpos ( ) " onMouseDown="down it ( ) " onMouseUp="up_it ( ) " onMouseMove="move_ it ( ) ">
Расставьте плашки перетаскиванием с помощью мыши
<DIV ID="maintab" STYLE="width: 400px; height: 400рх; position: absolute; top: 100px;">
<TABLE BGCOLOR="#C0C0C0" WIDTH="100%" CELLSPACING="0" CELLPADDING="0" BORDER="1">
<TR>
<TD><IMG SRC="Images/diafano1.gif" WIDTH="98" HEIGHT="98"></TD>
<TD><IMG SRC="Images/diafano1.gif" WIDTH="98" HEIGHT="98"></TD>
<TD><IMG SRC="Images/diafano1.gif" WIDTH="98" HEIGHT="98"></TD>
<TD><IMG SRC="Images/diafano1.gif" WIDTH="98" HEIGHT="98"></TD>
</TR> <TR>
<TD><IMG SRC="Images/diafano1.gif" WIDTH="98" HEIGHT="98"></TD>
<TD><IMG SRC="Images/diafano1.gif" WIDTH="98" HEIGHT="98"></TD>
<TD><IMG SRC="Images/diafano1.gif" WIDTH="98" HEIGHT="98"></TD>
<TD><IMG SRC="Images/diafano1.gif" WIDTH="98" HEIGHT="98"></TD>
</TR> <TR>
<TD><IMG SRC="Images/diafano1.gif" WIDTH="98" HEIGHT="98"></TD>
<TD><IMG SRC="Images/diafano1.gif" WIDTH="98" HEIGHT="98"></TD>
<TD><MG SRC="Images/diafano1.gif" WIDTH="98" HEIGHT="98"></TD>
<TD><IMG SRC="Images/diafano1.gif" WIDTH="98" HEIGHT="98"></TD>
</TR> <TR>
<TD><IMG SRC="Images/diafano1.gif" WIDTH="98" HEIGHT="98"></TD>
<TD><IMG SRC="Images/diafano1.gif" WIDTH="98" HEIGHT="98"></TD>
<TD><IMG SRC="Images/diafano1.gif" WIDTH="98" HEIGHT="98"></TD>
<TD><IMG SRC="Images/diafano1.gif" WIDTH="98" HEIGHT="98"></TD>
</TR>
</ TABLE >
</DIV>
<IMG ID="p11" SRC="Images/digit11.gif" WIDTH="100" HEIGHT="100" BORDER="0" ALT="11" STYLE="position : absolute; top: 60px; left: 50px;">
<IMG ID="p12" SRC="Images/digit12.gif" WIDTH="100" HEIGHT="100" BORDER="0" ALT="12" STYLE="position : absolute; top: 160px; left: 50px;">
<IMG ID="p13" SRC="Images/digit13.gif" WIDTH="100" HEIGHT="100" BORDER="0" ALT="13" STYLE="position : absolute; top: 260px; left: 50px;">
<IMG ID="p14" SRC="Images/digit14.gif" WIDTH="100" HEIGHT="100" BORDER="0" ALT="14" STYLE="position: absolute; top: З60рх; left: 50px;">
<IMG ID="p15" SRC="mages/digit15.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: З60рх; left: 30px;">
<IMG ID="p10" SRC="Images/digit10.gif" WIDTH="100" HEIGHT="100" BORDER="0" ALT="10" STYLE="position: absolute; top: 460px; left: 30px;">
<IMG ID="p1" SRC="Images/digit1.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" HEIGHT="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.12. В принципе, в такую игру уже можно по-настоящему играть. Конечно, этот код можно еще упростить. Правильно, зачем шестнадцать раз повторять тег вставки прозрачного рисунка? Давайте заменим его вложенным циклом JavaScript:

for (var k=1; k<=4; k++) {
document.write("<TR>");
for (var m=1; m<=4; m++) document.write('<TD>
<IMG SRC="Images/diafano1.gif" WIDTH="98" HEIGHT="98">
</TD>');
document.write("</TR>") ;
}

Рис.7.12.Реализация технологии drag-and-drop: пользователь может перетаскивать плашки с помощью мыши

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

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

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

Hosted by uCoz