My.BezDoz.ru

Категории раздела
Games not toys
Техно
Прогулка по сети
Мобайл
Компьютеры
Интернет
Андроид | Android
Программирование
Планшет
Поиск
Меню сайта
Главная » Статьи » Программирование

JavaScript. События, обработка событий
JavaScript. События, обработка событий

Окулист: Вы с охоты? Несчастный случай? Пыж угодил в глаз?
Внук: Э, не. Дедушка еще только будет стрелять.
Окулист: Значит, несчастный случай еще впереди. <...>
Внук: <...> Очки бы вот ему.
Окулист: Зрение беспокоит?
Внук: Да нет. Просто дедушка плохо видит. Вот дадут ему очки, он тут же пульнет.

Славомир Мрожек. "Кароль".

Глава 11. События в JavaScript 1.2
Новые события

Ранее мы уже упоминали о том, что Java-Script 1.2 имеет возможность обрабатывать новые события, которые не описаны в более ранних версиях языка. В таблице, расположенной ниже, перечислены события Java-Script 1.2:
Abort
Focus
MouseOut
Submit
Blur
KeyDown
MouseOver
Unload
Click
KeyPress
MouseUp
Change
KeyUp
Move
DblClick
Load
Reset
DragDrop
MouseDown
Resize
Error
MouseMove
Select

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

<html>
<head>
<script language="JavaScript">
window.onresize= message;
function message() {
alert("Размер окна был изменен!");
}
</script>
</head>
<body>
Измените размер окна.
</body>
</html>

При помощи строчки

window.onresize= message; мы задаем действие, которое будет осуществлено при наступлении события Resize. Мы определили средство управления событием onResize. Функция message() будет выполнена при изменении размеров окна. Здесь мы определили средство обработки события новым для нас способом, однако этот способ не является новым для JavaScript 1.2. Вернемся к ранее рассмотренным примерам. Если мы хотим определить средство обработки события, связанного с нажатием кнопки, то мы можем написать программу привычным способом, как мы это делали ранее:
<form name="myForm">
<input type="button" name="myButton" onClick="alert('Click event occured!')">
</form>
Тот же смысл несет в себе следующий текст программы:
<form name="myForm">
<input type="button" name="myButton">
</form>
...
<script language="JavaScript>
document.myForm.myButton.onclick= message;
function message() {
alert('Click event occured!');
}
</script>

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

Здесь необходимо сделать два замечания. Первое: не следует писать window.onResize, можно пользоваться только прописными буквами, т.е. писать window.onresize. Второе: после слова message мы не должны писать скобки, т.е. мы не можем написать window.onresize=message(). Если мы напишем такую строчку (что будет ошибкой в нашем случае), то броузер воспримет message() как обращение к функции, чего не должно быть в нашем случае, так как мы не требуем обращения к функции, но лишь хотим определить средство обработки события.

Объект Event (событие)

В языке JavaScript 1.2 определен новый объект, это объект Event. Объект Event обладает свойствами, эти свойства соответствуют свойствам, понятным по обычным жизненным ситуациям. Рассмотрим пример: если на приведенной ниже картинке вы щелкнете мышкой, то появится новое окно, в котором будут написаны координаты точки, на которой расположена мышка.



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

<layer>
<a href="#" onClick="alert('x: ' + event.x + ' y: ' + event.y); return false;">
<img src="davinci.jpg" width=209 height=264 border=0></a>
</layer>

Здесь мы используем средство обработки событий onClick, расположенное внутри ярлыка <a>, что мы могли бы писать и в старых версиях JavaScript. Новым здесь является то, что далее мы используем событие event и посредством event.x и event.y обращаемся к его свойствам (в данном случае это координаты точки щелчка), для того чтобы вывести координаты положения точки щелчка во всплывающем окне. Здесь мы использовали объект Event для того, чтобы определить координаты события. Здесь мы поместили весь пример внутри слоя (текст программы размещен после ярлыка <layer>), поэтому мы получим координаты относительно этого слоя, в нашем случае весь слой состоит из рисунка, и координаты будут выдаваться относительно этого рисунка. Если бы мы не размещали наш пример в слое, то координаты были бы определены относительно окна броузера. Инструкция return false здесь используется для того, чтобы броузер не переходил по указанной ссылке, а игнорировал ее.

Объект Event обладает следующими свойствами (некоторые из них мы рассмотрим далее в примерах):

Перехват событий

Еще одно важное свойство v это возможность перехвата событий. Если вы, например, щелкаете кнопку мыши, то происходит событие Click и выполняется инструкция, указанная в средстве обработки события onClick. При помощи перехвата событий можно сделать так, что окно, документ или слой "перехватят" данное событие до того, как оно будет обработано. Рассмотрим пример, чтобы понять, что в этом свойстве есть полезного.

<html>
<head>
<script language="JavaScript">
window.captureEvents(Event.CLICK);
window.onclick= handle;
function handle(e) {
alert("Объект window перехватил событие Click!");
return true; // выполняем инструкции далее, т.е. переходим по ссылке
}
</script>
</head>
<body>
<a href="test.htm">Нажмите эту ссылку</a>
</body>
</html>

В этом примере (пример загружается в отдельное окно) после того, как мы нажмем указанную ссылку, появляется новое окно с пре-дупреждением "Объект window перехватил событие Click". В окне предупреждения содержится кнопка "ОК". После того как мы щелкаем эту кнопку, происходит переход по указанной ссылке. Здесь мы не описывали средство обработки события внутри ярлыка <a>, вместо этого мы написали строчку:

window.captureEvents(Event.CLICK);

Это позволило нам перехватить событие Click при помощи объекта window. При обычных обстоятельствах объект window "не знаком" с событием Click, но при помощи свойства перехвата мы имеем возможность перенаправить это событие и связать его с объектом window. Заметьте, что мы пишем Event.CLICK, здесь CLICK должно быть написано заглавными буквами. Если существует необходимость осуществить захват нескольких событий, то эти события должны быть перечислены и отделены друг от друга вертикальной чертой "|". Вот пример:

window.captureEvents(Event.CLICK | Event.MOVE);

Здесь мы записали инструкцию return true; внутри функции handle(), которую мы указали как функцию, служащую средством обработки события onClick. Это означает, что броузер перейдет по указанной ссылке сразу после выполнения функции handle(). Если же мы напишем вместо return true строчку return false, то все действия, которые должны были произойти при наступлении события Click, не будут выполнены.

Если мы определим средство обработки событий onClick внутри ярлыка <a>, то мы увидим, что в этом случае наше средство обработки события не будет работать. Это очевидно, поскольку объект window перехватывает событие перед тем, как он обращается к объекту ссылки (link).

Если мы опишем функцию handle() таким образом:

function handle(e) {
alert("The window object captured this event!");
window.routeEvent(e);
return true;
}

то компьютер будет проверять, существуют ли для данного события еще иные средства обработки. Переменная e v это наш объект Event, который передается посредством нашей функции handle(e).

Мы также имеем возможность осущест-влять пересылку событий прямо какому-либо конкретному объекту. Для этого мы можем использовать метод handleEvent(). Пример выглядит так:

<html>
<script language="JavaScript">
window.captureEvents(Event.CLICK);
window.onclick= handle;
function handle(e) {
document.links[1].handleEvent(e);
}
</script>
<a href="test.htm">Щелкните эту ссылку</a><br>
<a href="test.htm"
onClick="alert('Средство обработки второй ссылки!');">Вторая ссылка</a>
</html>

Все события Click будут направлены на вторую ссылку, даже в том случае, если вы не нажимаете эту ссылку непосредственно!

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

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

<html>
<script language="JavaScript">
window.captureEvents(Event.KEYPRESS);
window.onkeypress= pressed;
function pressed(e) {
alert("Нажата клавиша, ее значение ASCII: " + e.which);
}
</script>
</html>

При нажатии клавиши на экране будет всплывать окно-предупреждение, содержащее строчку "Нажата клавиша, ее ASCII-значение:

...", вместо точек будет указано ASCII-значение нажатой клавиши.
Глава 12: Перетаскивание.
Что такое перетаскивание?

Перетаскивание v перевод английского термина drag & drop. Перетаскивание v это выбор элемента при помощи нажатия кнопки мыши и перемещение этого элемента в новое место, при этом кнопка мыши удерживается в нажатом положении и отпускается лишь тогда, когда перетаскиваемый элемент (курсор) находится там, куда предполагается перетащить выбранный элемент.

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

<html>
<head>
<script language="JavaScript">
<!--
var dragObj= new Array();
var dx, dy;
window.captureEvents(Event.MOUSEDOWN | Event.MOUSEUP);
window.onmousedown= startDrag;
window.onmouseup= endDrag;
window.onmousemove= moveIt;
function startDrag(e) {
currentObj= whichObj(e);
window.captureEvents(Event.MOUSEMOVE);
}
function moveIt(e) {
if (currentObj != null) {
dragObj[currentObj].left= e.pageX v dx;
dragObj[currentObj].top= e.pageY v dy;
}
}
function endDrag(e) {
currentObj= null;
window.releaseEvents(Event.MOUSEMOVE);
}
function init() {
dragObj[0]= document.layers["layer0"];
dragObj[1]= document.layers["layer1"];
dragObj[2]= document.layers["layer2"];
}
function whichObj(e) {
// проверка того, какой объект выбран
var hit= null;
for (var i= 0; i < dragObj.length; i++) {
if ((dragObj[i].left < e.pageX) &&
(dragObj[i].left + dragObj[i].clip.width > e.pageX) &&
(dragObj[i].top < e.pageY) &&
(dragObj[i].top + dragObj[i].clip.height > e.pageY)) {
hit= i;
dx= e.pageX- dragObj[i].left;
dy= e.pageY- dragObj[i].top;
break;
}
}
return hit;
}
// -->
</script>
</head>
<body onLoad="init()">
<layer name="layer0" left=100 top=200 clip="100,100" bgcolor="#0000ff">
<font size=+1>Object 0</font>
</layer>
<layer name="layer1" left=300 top=200 clip="100,100" bgcolor="#00ff00">
<font size=+1>Object 1</font>
</layer>
<layer name="layer2" left=500 top=200 clip="100,100" bgcolor="#ff0000">
<font size=+1>Object 2</font>
</layer>
</body>
</html>

JavaScript не поддерживает перетаскивания в явном виде, т.е. в языке нет такого свойства, которым бы описывалось перетаскивание, т.е. у объекта Image нет свойства, назовем его, например, dragging, задавая которое можно было бы легко и просто осуществлять перетаскивания. Для того чтобы организовать перетаскивание, необходимо написать программу. Радует то, что программа эта не будет сложной.

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

События Mouse и JavaScript 1.2

Итак, какие события мы будем использовать? В нашем распоряжении нет события, которое в явном виде задавало бы перетаскивание, однако мы можем достичь своей цели, используя события MouseDown, MouseMove и MouseUp. Если пользователь нажмет где-нибудь в окне броузера кнопку мыши, то наша программа должна будет прореагировать на это событие и определить, на каком объекте (на каком слое) находится указатель мыши в момент нажатия кнопки. Нам нужны координаты данного события. Для этого мы имеем объект Event, с помощью его свойств мы легко можем получить координаты события.

Второй важный момент v это то, что мы имеем возможность организовать захват события. Если мы, скажем, нажимаем кнопку, то событие нажатия кнопки посылается сразу непосредственно объекту button. Но в нашем случае нам необходимо сделать так, чтобы объект window смог обработать наступившее событие (нажатие кнопки мыши). Мы создаем ситуацию, когда объект window получает захваченное событие и реагирует на него. Следующий пример показывает, как это происходит в случае с событием Click. Вы можете щелкнуть мышью в любом месте в пре-делах окна броузера, в ответ появится новое окно с предупреждением, в котором будут указаны координаты мыши, т.е. координаты места щелчка мышью.

Так выглядит текст программы:

<html>
<script language="JavaScript">
<!--
window.captureEvents(Event.CLICK);
window.onclick= displayCoords;
function displayCoords(e) {
alert("x: " + e.pageX + " y: " + e.pageY);
}
// -->
</script>
Щелкните где-нибудь в окне броузера.
</html>

Первое, что мы потребовали от объекта window, v это осуществить перехват события Click. Для этого мы использовали метод captureEvent(). Строчка window.onclick= displayCoords; задает то, что будет происходить в случае наступления события Click. Эта инструкция сообщает броузеру, что в случае наступления события Click необходимо вызвать функцию displayCoords(). Здесь при описании средства обработки события не следует использовать скобки после выражения displayCoords, поскольку здесь мы описываем средство обработки события, передавая ему лишь имя функции, но не саму функцию. Функция displayCoords() выглядит следующим образом:

function displayCoords(e) {
alert("x: " + e.pageX + " y: " + e.pageY);
}

Мы видим, что функция имеет один аргумент. Это объект Event, который передается этой функции для обработки. У этого объекта есть свойства pageX и pageY, которые содержат значения координат данного события. Окно предупреждения выводит на экран именно эти значения.
События MouseDown, MouseMove и MouseUp

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

Текст программы очень сильно похож на текст предыдущего примера:

<html>
<script language="JavaScript">
<!--
window.captureEvents(Event.MOUSEMOVE);
window.onmousemove= displayCoords;
function displayCoords(e) {
status= "x: " + e.pageX + " y: " + e.pageY;
}
// -->
</script>
Координаты мыши показаны в строке состояния.
</html>

Здесь необходимо писать выражение Event.MOUSEMOVE, причем MOUSEMOVE должно быть написано заглавными буквами. Однако при определении средства обработки события мы должны использовать строчные буквы: window.onmousemove= displayCoords.

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

Текст программы:

<html>
<script language="JavaScript">
<!--
window.captureEvents(Event.MOUSEDOWN | Event.MOUSEUP);
window.onmousedown= startDrag;
window.onmouseup= endDrag;
window.onmousemove= moveIt;
function startDrag(e) {
window.captureEvents(Event.MOUSEMOVE);
}
function moveIt(e) {
// показываем координаты
status= "x: " + e.pageX + " y: " + e.pageY;
}
function endDrag(e) {
window.releaseEvents(Event.MOUSEMOVE);
}
// -->
</script>
Нажмите кнопку и перемещайте мышь по экрану.
Координаты мыши показаны в строке состояния.
</html>

Здесь мы, как это было и в предыдущих примерах, первым делом заставляем объект windоw перехватить события. Сейчас перехватываемыми событиями являются события MouseDown и MouseUp:

window.captureEvents(Event.MOUSEDOWN | Event.MOUSEUP);

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

window.onmousedown= startDrag;
window.onmouseup= endDrag;

Следующая строчка определяет еще одно средство обработки события MouseMove. Она указывает, что будет происходить при движении мыши:

window.onmousemove= moveIt;

Однако мы не определили Event.MOUSEMOVE, а значит, это событие не будет захвачено объектом window. И кажется, что мы зря обращаемся к функции moveIt при помощи той строчки, что написана выше, по-скольку событие MousMove не достигнет объекта windоw. Не спешите, посмотрите на функцию startDrag(), обращение к ней происходит сразу же после того, как наступит событие MouseDown:

function startDrag(e) {
window.captureEvents (Event.MOUSEMOVE);
}

Сейчас мы видим, что объект window на-деляется возможностью осуществлять перехват событий MouseMove сразу после того, как нажимается кнопка мыши. Мы должны позаботиться и о том, чтобы объект window не смог захватывать событие MouseMove после того, как кнопка мыши была отпущена. Это делает функция endDrag(), в которой использован метод release-Events():

function endDrag(e) {
window.releaseEvents (Event.MOUSEMOVE);
}

Функция moveIt() также показывает координаты мыши в строке состояния.

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

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

Это можно сделать следующим образом: 

<html>
<head>
<script language="JavaScript">
<!--
var dragObj= new Array();
var dx, dy;
window.captureEvents(Event.MOUSEDOWN | Event.MOUSEUP);
window.onmousedown= startDrag;
window.onmouseup= endDrag;
window.onmousemove= moveIt;
function startDrag(e) {
currentObj= whichObj(e);
window.captureEvents(Event.MOUSEMOVE);
}
function moveIt(e) {
if (currentObj != null) {
dragObj[currentObj].left= e.pageX v dx;
dragObj[currentObj].top= e.pageY v dy;
}
}
function endDrag(e) {
currentObj= null;
window.releaseEvents(Event.MOUSEMOVE);
}
function init() {
dragObj[0]= document.layers["layer0"];
dragObj[1]= document.layers["layer1"];
dragObj[2]= document.layers["layer2"];
}
function whichObj(e) {
// определяем, какой объект "щелкнут" мышкой
var hit= null;
for (var i= 0; i < dragObj.length; i++) {
if ((dragObj[i].left < e.pageX) &&
(dragObj[i].left + dragObj[i].clip.width > e.pageX) &&
(dragObj[i].top < e.pageY) &&
(dragObj[i].top + dragObj[i].clip.height > e.pageY)) {
hit= i;
dx= e.pageX- dragObj[i].left;
dy= e.pageY- dragObj[i].top;
break;
}
}
return hit;
}
// -->
</script>
</head>
<body onLoad="init()">
<layer name="layer0" left=100 top=200 clip="100,100" bgcolor="#0000ff">
<font size=+1>Object 0</font>
</layer>
<layer name="layer1" left=300 top=200 clip="100,100" bgcolor="#00ff00">
<font size=+1>Object 1</font>
</layer>
<layer name="layer2" left=500 top=200 clip="100,100" bgcolor="#ff0000">
<font size=+1>Object 2</font>
</layer>
</body>
</html>

Мы задали три слоя, которые описаны в теле страницы после ярлыка <body>. После того как вся страница будет загружена, происходит обращение к функции init(), которая вызывается средством управления событием onLoad, которое мы расположили в ярлыке <body>:

function init() {
dragObj[0]= document.layers["layer0"];
dragObj[1]= document.layers["layer1"];
dragObj[2]= document.layers["layer2"];
}

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

window.captureEvents (Event.MOUSEDOWN | Event.MOUSEUP);
window.onmousedown= startDrag;
window.onmouseup= endDrag;
window.onmousemove= moveIt;
В функции startDrag() добавлена строчка:
currentObj= whichObj(e);

Функция whichObj() определяет тот объект, который был выбран пользователем, т.е. тот объект, на котором щелкнула мышка. Функция возвращает число v номер слоя. Если не выбран ни один слой, то функция возвращает значение null. Возвращаемое значение хранится в переменной currentObj.

В функции whichObj() осуществляется проверка значений свойств left, top, width и height каждого слоя. С помощью такой проверки происходит определение того, какой слой был выбран щелчком мыши.

Кидание объектов

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

Как определить, кинул покупатель предметы в корзину или нет? Для этого нам нужно знать координаты объекта непосредственно после события MouseUp. Для этого нам необходимо добавить несколько инструкций в функцию endDrag(). Мы, например, можем установить проверку того, попадают ли координаты мыши в пределы установленной прямоугольной области (соответствующей корзине), если координаты попадают в эту область, то можно, например, осуществить обращение к функции, которая регистрирует факт покупки путем, скажем, размещения покупаемых объектов в массиве. Демонстрируя элементы этого массива, мы показываем предметы, расположенные в корзине.

Конечно, наша программа не лишена недостатков. Может показаться странным, что перетаскиваемый объект вдруг оказывается позади покоящегося объекта. Эту задачу можно решить, если изменить порядок следования объектов, задав новый порядок внутри функции startDrop(). Конечно, объекты в виде красной, синей и зеленой фигур v это не лучший пример. Вы можете использовать более изящные картинки, описав их при помощи ярлыка <img>. Более того, в пределах каждого слоя можно использовать и любые другие объекты.

В. Будилов, М.Райт

Понравился материал?







Ссылка для Форума:
Прямая ссылка

Категория: Программирование
Просмотров: 1584 | Рейтинг: 0.0/0
Всего комментариев: 0
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]
BezDoz.Ru
Форма входа
Техно
По теме
Статистика

Онлайн всего: 1
Гостей: 1
Пользователей: 0

Copyright MyCorp © 2017
Бесплатный конструктор сайтов - uCoz