В объекте события содержится подробнейшая информация о том, что и где произошло.
К сожалению, здесь много кросс-браузерных несовместимостей, однако самые важные из них легко преодолимы.
Тип события можно получить, используя кроссбраузерное свойство type объекта событие.
function getEventType(e) {
if (!e) e = window.event;
alert(e.type);
}
Данный код в действии (в примере обрабатываются события click и mouseout):
targetЧаще всего нужно узнать, на каком элементе сработало событие.
Например, мы поймали на внешнем div'е и хотим знать, на каком из внутренних элементов оно на самом деле произошло.
В Internet Explorer у объекта window.event для этого есть свойство srcElement, в остальных браузерах, работающих по рекомендациям W3C, для этого используется event.target.
Вот пример использования этого свойства. Обработчик стоит только на внешнем диве, но благодаря event.target выводит по клику класс исходного элемента.
<div class="d1"
onclick="*!*t=event.target||event.srcElement; alert(t.className)*/!*"
>
<span class="number">1</span>
<div class="d2">
<span class="number">2</span>
<div class="d3">
<span class="number">3</span>
</div>
<a class="d2a" href="javascript:void(0)">Ссылка</a>
</div>
</div>
Javascript-обработчик в примере висит только на внешнем диве d1 и выглядит примерно так:
function(event) {
// получить объект событие.
// вместо event лучше писать window.event
event = event || window.event
// кросс-браузерно получить target
var t = event.target || event.srcElement
alert(t.className)
}
relatedTargetДля событий mouseout и mouseover предусмотрен способ получить как элемент на который курсор мыши перешел, так и элемент, с которого он перешел.
Эти свойства - relatedTarget в W3C, и fromElement/toElement в Internet Explorer.
// Обработчик для mouseover
function mouseoverHandler(event) {
event = event || window.event
var relatedTarget = event.relatedTarget || event.fromElement
// для mouseover
// relatedTarget - элемент, *!*с которого*/!* пришел курсор мыши
}
// Обработчик для mouseout
function mouseoutHandler(event) {
event = event || window.event
var relTarg = event.relatedTarget || event.toElement
// для mouseout
// relatedTarget - элемент, *!*на который*/!* перешел курсор мыши
}
Свойство relatedTarget дополняет target. В нем всегда находится информация о втором элементе, участвовавшем в событии.
Поэтому его можно получить для IE, взяв то свойство из fromElement/srcElement, которое не равно target:
if (!e.relatedTarget && e.fromElement) {
e.relatedTarget = (e.fromElement==e.target) ? e.toElement : e.fromElement
}
thisПри всплытии - событие по очереди вызвает обработчики на элементе-триггере и дальше, вверх по документу.
По мере всплытия, текущим элементом каждый раз становится новый. Иначе говоря. текущий элемент - это тот, к которому в данный момент "доплыло" событие.
Стандартный способ получить текущий элемент - использовать переменную this.
Например, при клике на внутренний div, код в этом примере последовательно отмечает элементы, на которых регистрируется всплывающее событие:
<div class="d1" onclick="highlightMe(this)">1
<div class="d2" onclick="highlightMe(this)">2
<div class="d3" onclick="highlightMe(this)">3</div>
</div>
</div>
which/button.После получения события обычно интересно узнать, какая кнопка была нажата. Если, конечно, это не событие contextmenu, с которым все и так понятно 
Для этого в объекте event есть два свойства: event.which и event.button, которые содержат числовые значения, соответствующие нажатой кнопке. К сожалению, тут есть некоторые несовместимости.
| Internet Explorer | Firefox, Safari Win и Opera | Konqueror | ||
| ЛЕВАЯ КНОПКА | event.which | undefined | 1 | 1 |
| event.button | 1 | 0 | 1 | |
| СРЕДНЯЯ КНОПКА | event.which | undefined | 2 | 2 |
| event.button | 4 | 1 | 4 | |
| ПРАВАЯ КНОПКА | event.which | undefined | 3 | 3 |
| event.button | 2 | 2 | 2 | |
Свойство event.which было изначально изобретено Netscape, а event.button использовалось в Internet Explorer.
Через некоторое время браузеры стали использовать оба и все перепуталось.
В стандарте W3C прописано свойство button, которое ведет себя, как в Firefox, т.е:
Подход создателей браузера Internet Explorer, вообще говоря, более универсальный, так как button является 3-битовым числом, каждый бит которого отвечает за кнопку мыши.
Так, button & 1 (первый бит) установлен в 1, если нажата левая кнопка, button & 2 (второй бит) установлен в 1, если нажата правая кнопка, и button & 4 (третий бит) - если нажата средняя.
В результате мы не можем отловить, когда, например, нажаты левая и правая кнопки, а когда только левая или только правая. К сожалению, это можно сделать только в IE.
Удобнее всего - взять за основу свойство which, которое одинаково поддерживают почти все браузеры.
Остается лишь составить which из button для Internet Explorer:
if (!e.which && e.button) {
if (e.button & 1) e.which = 1
else if (e.button & 4) e.which = 2
else if (e.button & 2) e.which = 3
}
Вот универсальный тестовый стенд по определению клавиш. Выбирайте любую мышь и жмите кнопу из любого браузера - ниже появятся названия событий и значения which/button.
clientX(Y)/pageX(Y)При обработке событий, связанных с мышью, нужен кроссбраузерный способ получения координат курсора из события в обработчике.
Координаты курсора мыши относительно окна находятся в стандартных свойствах clientX/clientY. Они одинаково поддерживается всеми браузерами.
Если у вас есть окно 500x500, и мышь находится в центре, то clientX и clientY будут оба равны 250. Если вы затем проскроллируете документ вниз, налево или вверх, не двигая курсор - значения clientX/clientY не изменятся, так как отсчитываются относительно окна, а не документа.
Как правило, при обработке события нужна позиция мыши относительно документа, учитывающая прокрутку. Стандарт W3C предоставляет для этого свойство pageX/pageY.
Если у вас есть окно 500x500, и мышь находится в центре, то pageX и pageY будут оба равны 250. Если вы затем проскроллируете на 250 пикселей вниз, pageY станет равным 750.
Таким образом pageX/pageY содержат координаты, на каком месте документа произошло событие, учитывая все прокрутки.
Свойства pageX/pageY поддерживаются всеми браузерами, кроме Internet Explorer.
В IE их можно получить из clientX/clientY, прибавив к ним scrollLeft/scrollTop.
Обычно оно находится в <body>: document.body.scrollLeft, но это не всегда так. Например, при выборе Strict DTD оно высчитывается для <html>: document.documentElement.scrollLeft. Кроме того, тэга <body> может просто не быть в документе.
Поэтому мы сначала возьмем html.scrollLeft (если есть), затем проверим body.scrollLeft. Если нет ни того, ни того, то 0.
var html = document.documentElement var body = document.body e.pageX = e.clientX + (html && html.scrollLeft || body && body.scrollLeft || 0)
Кроме того, document в IE может быть немного сдвинут с позиции 0,0. Значение сдвига находится в document.documentElement.clientLeft/clientTop, и его также необходимо учесть.
Этот код позволяет надежно получить pageX/pageY для IE, в котором его изначально нет:
if (e.pageX == null && e.clientX != null ) {
var html = document.documentElement
var body = document.body
e.pageX = e.clientX + (html && html.scrollLeft || body && body.scrollLeft || 0) - (html.clientLeft || 0)
e.pageY = e.clientY + (html && html.scrollTop || body && body.scrollTop || 0) - (html.clientTop || 0)
}
Этот обработчик mouseMove обновляет координаты мыши относительно документа.
function mouseShowHandler(e){
e = e || window.event
if (e.pageX == null && e.clientX != null ) {
var html = document.documentElement
var body = document.body
e.pageX = e.clientX + (html && html.scrollLeft || body && body.scrollLeft || 0) - (html.clientLeft || 0)
e.pageY = e.clientY + (html && html.scrollTop || body && body.scrollTop || 0) - (html.clientTop || 0)
}
document.getElementById('mouseX').value = e.pageX
document.getElementById('mouseY').value = e.pageY
}
Координата X:
Координата Y:
Вы узнали, как работают и как кросс-браузерно получить основные свойства объекта события:
thisevent.type
event.target/relatedTargetevent.whichevent.clientX/clientYevent.pageX/pageYКроме того, увидели их в действии на демо.
Этих свойств хватает для 95% задач, связанных с событиями.