14. Обработка событий
Модель событий IE5+
![]() Иллюстрация с сайта www.oszone.net |
Через IE5+ обозначены браузеры фирмы Microsoft от версии 5.0 и выше. Когда модель W3C была стандартизована и ее поддержка реализована в браузерах, Microsoft, как обычно, снова пошла своим путем, создав собственную модель (назовем ее условно модель IE5+) и дополнительную головную боль web-разработчикам. |
Про то, что объект Event в браузерах IE не передается в обработчик, а является глобальным свойством window.event, мы уже говорили, описывая модель уровня 0. Говорили также о разнице в способах, реализующих прерывание распространения события и отмены обработки события по умолчанию.
Все эти отличия (и рассмотренные способы борьбы с ними) остаются в силе и в рамках моделей W3C/IE5+.
Рассмотрим теперь, как регистрируются обработчики в модели IE5+.
В IE5 и более поздних версиях (по крайней мере, по IE-7 включительно) обработчики регистрируются методом attachEvent, а удаляются методом detachEvent. Ниже описаны форматы этих методов (они принадлежат интерфейсам Element и Document в моделе IE5+).
Аргументы:
- eventType — строка, тип события, для которого будет вызываться обработчик. Тип события совпадает с именем событийного свойства или атрибута ранней модели DOM (с префиксом «on»). Например, "onclick", "onmouseover", "onmouseout".
- listener — ссылка на функцию-обработчик. Функция вызывается без аргументов (то есть объект Event в неё не передается). Кроме того, функция вызывается в контексте глобального объекта window, следовательно, ключевое слово this в обработчике связано с window, а не с объектом, к которому обработчик привязан.
Метод удаляет указанную функцию-обработчик события. Аргументы должны иметь те же значения, что и при вызове метода attachEvent.
Вероятно, вы обратили внимание, что среди аргументов методов attachEvent и detachEvent отсутствует аргумент useCupture. Можно считать, что он всегда равен false, ибо в модели IE5+ реализована только фаза всплытия, а фаза захвата отсутствует.
Как быть, если желательно (а это желательно практически всегда) чтобы наше приложение работало во всех браузерах?
Приходится, либо работать только с моделью уровня 0, либо регистрировать обработчики с ветвлением, которое проверяет функциональные возможности браузера. Что-то вроде такого кода:
if (element.addEventListener) // Если работает модель DOM W3C
{
element.addEventListener(...);
element.addEventListener(...);
...
}
else if (element.attachEvent) // Если работает модель IE5+
{
element.attachEvent(...);
element.attachEvent(...);
...
}
else // Старый браузер, такой как IE4
{
...
Либо проигнорировать старый браузер,
либо зарегистрировать обрабочики, как
свойства объекта element
...
}
Как уже отмечалось, модель IE5+ не реализует фазу захвата события. Иногда это может оказаться критично, например, в задаче о перетаскивании элемента по экрану. Элемент может не поспеть за движением мыши, выйти из-под неё, и, следовательно, перестать реагировать на событие mousemove. Чтобы этого не случилось, нужно «ловить» событие на фазе захвата, к какому бы элементу оно не спускалось от корня.
В модели IE5+ фаза захвата не реализована, и Microsoft была вынуждена добавить в интерфейсы Element и Document два метода — setCapture и relaseCapture.
В большинстве случаев метод setCapture вызывается в ответ на событие mousedown, что гарантирует получение событий мыши тем же самым элементом (в контексте которого метод был вызван). Элемент выполняет действия по перетаскиванию в ответ на событие mousemove и вызывает метод relaseCapture в ответ на событие mouseup.
Захват событий мыши, организованный методом setCapture может быть прерван, если браузер теряет фокус ввода, вызывает модальное окно alert или открывает системное меню. В подобных случаях генерируется событие losecapture (потеря захвата). Приложения, как правило, обрабатывают событие losecapture обработчиком, предусмотренным для события mouseup.
Пример 4, описанный в следующей части этой заметки, демонстрирует работу с методами setCapture, relaseCapture и событием losecapture при построении перетаскивания картинок по экрану, работающего во всех браузерах.