Событийная модель реализуется по-разному в IE и Firefox. В IE, есть явный объект window.event, который содержит подробности о произошедшем событии (например: OnClick), в тот момент когда оно происходит, в то время как в Firefox и других W3C совместимых браузерах, объект event автоматически передается в функцию - обработчик события,в качестве аргумента, и содержит аналогичную информацию о событии. Для кросс браузерной обработки событий это нужно обходить так:

document.onclick=function(e){
 var evt=window.event || e //evt автоматически выберет из двух значений нужное
 alert(evt.clientX) //что-то делаем с evt
}

 Кроме доступа к объекту, браузеры поддерживают разные поля и методы объекта event.  Ниже перечислены основные отличия и способы их обхода.

Объект event в IE  

В IE, объект event полностью доступен через глобальный объект window.event. Он поддерживает следующие свойства: 

Поля Описание Эквиваленты в других браузерах
altKey, ctrlKey, shiftKey Логические свойства, которые указывают были ли нажаты клавиши Alt, Ctrl, Shift на момент события. те же
button Целое число, указывающее, какая кнопка мыши была нажата или отпущена,1 -  левая, 2 - правый, 4 - по середине. Если были нажаты несколько кнопок, то значение содержит сумму величин обеих кнопок, например, 3 (1 +2) для левой и правой. В браузерах Firefox, то же свойство возвращает другие номера. Вот пример:
document.onmousedown=function(e){
var evt=window.event || e 
alert(evt.button)
}

  Если вы хотите определить, когда была нажата правая кнопка мыши, чтобы подавить дефолтное контекстном меню браузера, вы просто делаете return false; внутри событий 'OnClick' или 'OnMouseDown'. В результате эти события подавляются. Т.е. сами события не происходят. Это не всегда приемлемо. Вместо этого лучше использовать oncontextmenu:

document.oncontextmenu=function(){
 return false //stops the browser context menu from appearing on right click
}
те же, только возвращает другие значения
cancelBubble

Предотвращает пузырьковое распространение события. Т.е. когда вы нажимаете на элемент, событие передается его родителю и так далее пока не дойдет до window.  В браузерах, отличных от IE, нужно использовать event.stopPropagation(). Перед тем как использовать этот метод, неплохо бы проверить на его существование:

function preventbubble(e){
 if (e && e.stopPropagation) //если метод stopPropagation поддерживается 
  e.stopPropagation()
 else
  event.cancelBubble=true
}
stopPropagation()
clientX, clientY

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

document.onmousemove=function(e){
 var evt=window.event || e //Кроссбраузерный объект события браузера 
 window.status=evt.clientX+" : "+evt.clientY
}

 

те же
fromElement, toElement Для событий mouseover и mouseout, эти поля отображают из какого элемента мышь ушла и в какой пришла, соответственно. В W3C/ Firefox событийная модель использует другое поле, "relatedTarget", которое в зависимости от типа события (mouseover или mouseout). Просто возвращает соответствующий элемент, т.е. mouseover - куда мы пришли, mouseout - откуда мы ушли.

Посмотрите "relatedTarget" в секции с Firefox дополнительную информацию по теме, плюс там вы увидите демонстрацию
relatedTarget
keyCode

Поле содержит Unicode представление для нажатой в данный момент клавиши на клавиатуре. Используя String.fromCharCode(keyCode) можно получить строковое представление

charCode
offsetX, offsetY

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

layerX, layerY
returnValue Отключает любое действие по умолчанию, которое свзяанно с данным событием.
В браузерах W3C/Firefox, вместо этого надо использовать e.preventDefault()
preventDefault()
srcElement

Элемент на котором произошло событие, может отличаться от того элемента, который это событие обработал. К примеру есть divA и внутри него divB. Обработчик ставим на divA. Но получается, что мы сперва нажимаем на divb и пузырьком событие передается дальше по иерархии. Так вот event.target возвратит divB.


Firefox и другие современные браузеры не поддерживают "srcElement", но вместо этого имеют эквивалент e.target. Для выравнивания этой разницы между всеми браузерами, вы можете проверить, поддерживает ли объект поле e.target, если нет, то используем e.srcElement. Пример:

function myevent(e){
 var evt=window.event || e
 evt.target=evt.target||evt.srcElement
 //... производим некоторое действие
}
target
type     Строка, указывающая тип события, такие как  "mouseover", "click", и т.д..

те же

 

Событийная модель Mozilla/ Firefox

В Firefox +, объект event передается, как первый параметр функции обработчика события.

поля

Поле Описание IE эквивалент

altKey, ctrlKey, metaKey, shiftKey

Логические свойства, которые указывают были ли нажаты клавиши Alt, Ctrl,Meta, Shift на момент события. Теже, за исключением того, что IE, не поддерживает "metaKey".
bubbles Логическое значение, указывающее, является ли событие пузырьковым не поддерживает
button Целое число, указывающее, какая кнопка мыши была нажата или отпущена, 0 - левая, 2 - правая, 1 - по середине. Несколько иначе чем в IE, как описано выше.  те же, только возвращает другие значения
cancelable Логическое значение, указывающее, может ли событие быть отменено не поддерживает
charCode unicode представление нажатой в момент события клавиши на клавиатуре. Для представления в виде строки используйте String.fromCharCode(which)  keyCode
clientX, clientY Возвращает координаты мыши в момент события по отношению к верхнему левому углу окна. То же, что в IE (см. выше для получения дополнительной информации).  те же
currentTarget  Рассмотрим пример, когда вы назначаете обработчик события нажатия на див divA, который содержит дочерний divB. При нажатии внутри divB, e.currentTarget  будет содержать ссылку на  Diva (элемент на котором стоит обработчик события), а e.target содержит ссылку на divB, т.е. возвращает элемент на котором произошло событие.    не поддерживает
eventPhase Целое значение, указывающее, какой фазой потока событий это событие обрабатывается. Одной из CAPTURING_PHASE (1), AT_TARGET (2) или BUBBLING_PHASE (3).   не поддерживает
layerX, layerY Возвращает координаты мыши относительно расположения (абсолютное или относительное) элемента в момент события. Если событие произошло за пределами расположения элемента, тогда вместо него используется левый верхний угол. IE вмето этого использует свойства OffsetX и OffsetY. offsetX, offsetY
pageX, pageY

Возвращает координаты мыши относительно верхнего левого угла видимой страницы на момент события.

Что эквивалентно:

pageX: window.pageXOffset + e.clientX

pageY: window.pageYOffset + e.clientY 

не поддерживает
relatedTarget

На событие "mouseover" свойство содержит указатель на элемент, который на который мышка пришла. На событие "mouseout" оно содержит ссылку на элемент с которого указатель ушел.

Поле "relatedTarget" (или "fromElement" и "toElement" в IE) используется для определения находится ли курсор мыши в данный момент в контейнере или уже покинула его. В связи с пузырьковым поведением событий, при наведении на любой элемент в контейнере или даже текст, произойдет событие "mouseout", и можно отследить как мышь переходит от одного вложенного события к другому.

В следующем примере показан ID элемента в который мышь пришла и из которого мышь ушла,  между событиями "mouseover" или "mouseout", соответственно.

Демо: 

 
 
 

Исходный код:

<div id="outerdiv" style="width:130px; height:130px; border:1px solid black; background:black; padding:30px;">
<div id="innerdiv" style="width:80px; height:80px; border:1px solid black; background:white; padding:20px"></div>
</div>

<div id="statusfrom"></div>
<div id="statusto"></div>



<script type="text/javascript">

function showtofrom(e){
 var evt=window.event || e
 if (evt.type=="mouseover"){ // для события onmouseover
  var fromElement=evt.fromElement || evt.relatedTarget
  statusdiv1.innerHTML='Из элемента: ' + fromElement.id
 }
 else{ //для события onmouseout
  var toElement=evt.toElement || evt.relatedTarget
  statusdiv2.innerHTML='В элемент: ' + toElement.id
 }
}

var statusdiv1=document.getElementById("statusfrom")
var statusdiv2=document.getElementById("statusto")

document.body.onmouseover=showtofrom
document.body.onmouseout=showtofrom

</script>
fromElement, toElement
screenX, screenY Возвращает координаты мыши относительно левого верхнего угла экрана, в момент когда событие произошло.  не поддерживает
target Элемент на котором произошло событие, может отличаться от того элемента, который это событие обработал. К примеру есть divA и внутри него divB. Обработчик ставим на divA. Но получается, что мы сперва нажимаем на divb и пузырьком соыбтие передается дальше по иерархии. Так вот event.target возвратит divB.  srcElement
timestamp Возвращает время (в миллисекундах) с 1/1/1970  до момента события, например, когда была нажата клавиша (OnKeyPress). Но не все события возвращения временную метку.  не поддерживает
type Строка, указывающая тип события, такие как  "mouseover", "click", и т.д.. те же
which наследство от NS4/NS6 + Unicode нажатой клавиши. Идентичный  "charCode" keyCode

Методы

Метод Описание IE Эквивалент
preventDefault()

Отменяет любые действия по умолчанию, связанный с событием. То же самое происходит, когда мы делаем return false в обработчике onclick элемента "a". В следующем примере отключается действие по умолчанию  всех ссылок на странице.

function disablelink(e){
 var evt=window.event || e
 if (evt.preventDefault) //поддерживает ли preventDefault?
  evt.preventDefault()
 else //для IE
  return false
}

var alllinks=document.getElementsByTagName("a")
for (var i=0; i<alllinks.length; i++){
 alllinks[i].onclick=disablelink
}

 

 

 

returnValue

stopPropagation()

Исключает событие из пузыря, т.е. предотвращает дальнейший ход волны события. В IE  event.cancelBubble=true делает тоже самое.

Рассмотрим divA, который содержит divB внутри. При привязке события click к divA и к divB, нажав внутри divB по умолчанию будет также вызвать событие за событием по восходящей, т.е. сначала для divB а затем к divB. Чтобы не допустить этого, вы можете вызвать stopPropagation() на узле divB, и событие, происходящие внутри него не продолжат путешествие вверх:

пример:

 
divB.onclick=function(e){
 if (e && e.stopPropagation) //если stopPropagation поддерживается
  e.stopPropagation()
 else
  event.cancelBubble=true
}

 

cancelBubble

 

Оставлять комментарии могут только зарегистрированные пользователи

Комментарии  

Владимир
# Владимир 30.09.2011 16:19
Благодарю за статью, то, что нужно для изучающих JS!



P.S.

Опечатка в самом конце статьи: т.е. сначала для divB а затем к divB.

Правильно: т.е. сначала для divB а затем к divA.