Модель событий 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 внутри цикла содержит имя свойства, а не его значение.