Событийная модель реализуется по-разному в 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.
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" оно содержит ссылку на элемент с которого указатель ушел. Демо: Исходный код: <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 |
Комментарии
P.S.
Опечатка в самом конце статьи: т.е. сначала для divB а затем к divB.
Правильно: т.е. сначала для divB а затем к divA.