Модель событий JavaScript 1.2

В JavaScript 1.2 введена новая модель событий:

Abort, Blur, Click, Change, Focus, DblClick, DragDrop, Error KeyDown, KeyPress, KeyUp, Load, MouseDown, MouseMove, MouseOut, MouseOver, MouseUp,Move Reset, Resize, Select, Submit, Unload.

Объект Event.

В язык JavaScript 1.2 добавлен новый объект Event. Он содержит свойства, описывающие событие. Каждый раз, когда происходит какое-либо событие, объект Event передается соответствующей программе обработки. Ниже обрабатывается событие нажатия кнопки мыши, и определяется, какая именно из них была нажата:

<html>

<head>

<script language = "javascript">

function whichButton(event)

{

if (event.button == 2)

{

alert("Вы щелкнули правой кнопкой мыши!");

}

else

{

alert("Вы щелкнули левой кнопкой мыши!");

}

}

</script>

</head>

<body onmousedown="whichButton(event)">

<p>Щелкните любой кнопкой мыши в любом месте документа</p>

</body>

</html>

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

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

В тэг <a> мы поместили программу обработки событий onClick, как это мы уже делали в предшествующих версиях JavaScript. Новое здесь заключается в том, что для создания окошка с сообщением мы используем event.x и event.y. А это как раз и есть объект Event, который здесь нам нужен, чтобы узнать координаты мыши.

К тому все команды помещены в тэг <layer>. Благодаря этому мы получаем в сообщении координаты относительно данного слоя, т.е. в нашем случае относительно самого изображения. В противном же случае мы получили бы координаты относительно окна браузера. (инструкция return false; используется здесь для того, чтобы браузер обрабатывал далее данную ссылку)

Объект Event получил следующие свойства:

Data - Массив адресов URL оставленных объектов, при событии DragDrop.

LayerX - Горизонтальное положение курсора (в пикселах) относительно слоя. В комбинации с событием Resize это свойство представляет ширину окна браузера.

LayerY - Вертикальное положение курсора (в пикселах) относительно слоя. В комбинации с событием Resize это свойство представляет высоту окна браузера.

modifiers - Строка, задающая ключи модификатора - ALT_MASK, CONTROL_MASK, META_MASK or SHIFT_MASK

pageX - Горизонтальное положение курсора (в пикселах) относительно окна браузера.

pageY - Вертикальное положение курсора (в пикселах) относительно окна браузера.

screenX- Горизонтальное положение курсора (в пикселах) относительно экрана.

screenY - Вертикальное положение курсора (в пикселах) относительно экрана.

target - Строка, представляющая объект, которому исходно было послано событие.

type - Строка, указывающая тип события.

which - ASCII-значение нажатой клавиши или номер клавиши мыши.

x - Синоним layerX.

y - Синоним layerY.

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

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

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

<html>

<head>

<script language="JavaScript">

window.captureEvents(Event.CLICK);

window.onclick= handle;

function handle(e) {

alert("Объект window перехватывает это событие!");

return true; // т.е. проследить ссылку

}

</script>

</head>

<body>

<a href="test.htm">Click on this link</a>

</body>

</html>

Как видно, мы не указываем программы обработки событий в тэге <a>. Вместо этого мы пишемwindow.captureEvents(Event.CLICK);с тем, чтобы перехватить событие Click объектом window. Обычно объект window не работает с событием Click. Однако, перехватив, мы затем его переадресуем в объект window. Заметим, что в Event.CLICK фрагмент CLICK должен писаться заглавными буквами. Если же Вы хотите перехватывать несколько событий, то Вам следует отделить их друг от друга символами |. Например:

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

Помимо этого в функции handle(), назначенной нами на роль обработчика событий, мы пользуемся инструкцией return true;. В действительности это означает, что браузер должен обработать и саму ссылку, после того, как завершится выполнение функции handle(). Если же Вы напишете вместо этого return false;, то на этом все и закончится.

Если теперь в тэге <a> Вы зададите программу обработки события onClick, то поймете, что данная программа при возникновении данного события вызвана уже не будет. И это не удивительно, поскольку объект window перехватывает сигнал о событии еще до того, как он достигает объекта link. Если же Вы определите функцию handle() как

function handle(e) {

alert("The window object captured this event!");

window.routeEvent(e);

return true;

}

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

Кроме того, Вы можете непосредственно послать сигнал о событии какому-либо объекту. Для этого Вы можете воспользоваться методом 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("Key pressed! ASCII-value: " + e.which);

}

</script>

</html>

Исключения: throw/catch/finally

Работа с исключениями в JavaScript организована, как и в C++ или Java:

try {

//...

throw {message: "err!"}

//..

}

catch (e) {

alert("Ошибка!"+e)

}

Блок try{} указывает выполнить код внутри блока. В случае ошибки осуществляется выход из этого блока и переход на блок обработки исключений:

catch (e) {}

Оператор throw {} генерирует объект – исключение, после чего осуществляется выход из блока try. Обычно при этом генерируются потомки встроенного класса Error:

throw new Error("server timeout")

Часто при перехвате исключений надо перехватить определенный класс исключений. Оператор catch такого не умеет, поэтому полный код обработки будет выглядить так:

try {

// код ...

} catch(e) {

// ловим нужное исключение

if (e instanceof ConnectionError) {

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

//reconnect …

} else {

// пробрасываем незнакомое исключение дальше

throw e

}

} finally {

// блок finally выполняется всегда,

// вне зависимости - было исключение или нет

}

В этом примере присутствует блок finally, взятый в javascript из java. В стандартной схеме try..catch..finally, код в finally выполнится при любом результате работы try/catch, и туда удобно ставить всякие очистки, уведомления о конце процесса.

<!-- пример pr16 -->

<html>

<head>

<title>Наша начальная страница</title>

</head>

<body>

<script type="text/javascript">

function showErrorInfo(e) {

document.write(e, ":<BR>");

document.write("Источник ошибки: ", (e.number >> 16) & 0x1FFF, "<BR>");

document.write("Номер ошибки: ", e.number & 0xFFFF, "<BR>");

document.write("Описание ошибки: ", e.description);

}

var x;

try {

x = y; // Ошибка: переменная y не определена

}

catch (e) { // Создает локальный объект e класса Error

showErrorInfo(e);

}

</script>

</body>

</html>

Будет выведено:

[objectError]: Источник_ошибки:10 Номер_ошибки:5009 Описание ошибки: 'y' - определение отсутствует

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

В JavaScript используются следующие виды объектов:

· пользовательские объекты, которые создаются пользователями с помощью конструктора и объекта Object;

· встроенные объекты языка JavaScript: String — строка; Array — массив; Date — дата и время; Math — математические функции;

· объекты браузера создаются автоматически при загрузке документа: window — объект верхнего уровня в иерархии объектов; location — содержит свойства, описывающие местонахождение текущего документа, например, адрес URL; history — содержит информацию обо всех ресурсах, к которым пользователь обращался во время текущего сеанса; navigator — содержит информацию о версии браузера;

Кроме этого, имеются объекты frames, screen а также методы setTimeout() и setInterval().

· объекты, связанные с тэгами HTML и стилями CSS — в соответствии с моделью DOM большинству тэгов HTML и стилей CSS соответствуют свойства объекта document, которые сами также являются объектами; document — содержит свойства innerText, innerHTML, textContent, которые относятся к текущему HTML-документу.

Методы: getElementById(), getElementByTopName.

Пользовательские объекты

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

function Book() {

}

Тогда создание экземпляра объекта типа book будет иметь вид:

var myBook = new Book();

Конструктор может обращаться к создаваемому объекту, используя указатель this, таким образом, мы можем добавить свойство создаваемому объекту:

function Book() {

this.paper = true;

}

var myBook = new Book();

alert(myBook.paper); //выведет на экран true

В конструктор можно передавать параметры, чтобы задать начальные свойства создаваемого объекта.

function Book(isPaper) {//конструктор с параметрами

if (isPaper) this.paper = true;

else this.paper = false;

}

var myBook = new Book(false);

alert(myBook.paper); //выведет на экран false

Прототипы

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

Book.prototype.paper = false;

Book.prototype.isPaperBook = function() {

if (this.paper) alert("This is a paper book");

else alert("This is not a paper book");

}

function Book(isPaper) {

if (isPaper) this.paper = true;

}

var myBook = new Book(true);

myBook.isPaperBook(); //выведет фразу «This is a paper book»

В этом примере показано создание метода объекта и свойства, причем, в прототипе описано, что свойство paper имеет значение false. Однако в конструкторе это свойство переопределяется, если при создании объекта конструктору передается параметр со значением true.

Хеш-таблицы в JavaScript

Объект Object в JavaScript представляет собой обычный ассоциативный массив или "хэш". Он хранит любые соответствия "ключ => значение" и имеет несколько методов. Следующие два варианта создания объекта эквивалентны:

var o = new Object()

var o = {}

Есть два способа добавления свойств в объект. Первый - точка, второй - квадратные скобки:

o.test = 5// эквивалентные записи

o["test"] = 5

var name = 'test'

o[name] = 5

Имя свойства "test" является ключом в ассоциативном массиве, по которому лежит значение 5.

Доступ к свойству осуществляется так же через точку или через квадратные скобки:

alert(o.test)

alert(o['test'])

Если у объекта нет такого свойства, то результат будет 'undefined'

Еще один пример:

var h = new Object();

h.property = 10;

var s = 'ty';

alert(h['proper' + s]);// то же самое, что и h.property.

Удаление свойств осуществляется с помощью оператора delete:

var h = new Object();

h['property'] = 10;

alert(delete h['property']);

//выведет на экран true

alert(h['property']);

//выведет на экран undefined

Последний пример – перебор всех свойств объекта:

var h = new Object();

...

var props = '';

for(var i in h)

props += i + ' : ' + h[i] + '\n';

alert(props);

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

Наши рекомендации