Отсебятина Статьи Проекты
Облако тегов
Web CMS CSS htaccess HTML Javascript MySQL Php Безопасность Мониторы Новостная лента Оптимизация Ошибки Разработка сайта Часы Юзабилити оптимизация ошибки

Борьба с onMouseout 2. Устранение мерцания

Отсебятина от 14 марта 2009 года.    Теги: Javascript HTML


В прошлой статье я очень смутно описал возможности борьбы с мерцанием элемента с onMouseout в Firefox при передвижении курсора внутри элемента по его дочерним узлам, привязав его к конкретной задаче. На этот раз предложу пару способов для устранения внезапного пропадания элемента.
На самом деле, проблема проявляется не только в Firefox. Просто в других браузерах она не заметна. Но решения я буду предлагать только для Firefox, поэтому в других браузерах код может не работать. При желании, эти решения можно прикрутить и к другим браузерам.



Проблема мерцания с onMouseout



Проведите мышкой во внутрь серого квадрата, а затем во внутрь появившегося желтого квадрата и обратно, в серый. Иногда желтый квадрат будет пропадать.


div

Смотреть код


Дело в том, что по умолчанию события, привязанные к элементу, "наследуются" его детьми (вложенными элементами). Как результат, когда мы наводим и выводим курсор из вложенного элемента, срабатывает обработчик события, который привязан к родителю, что приводит к мерцанию элемента или исчезновению вовсе (в зависимости от кода. В нашем случае элемент исчезает). Плюс ко всему, при наведении курсора на дочерний элемент, срабатывает onMouseout родительского.
Получается, что при наведении курсора на дочерний элемент, он исчезает, но тут же срабатывает функция onMouseover, "наследованная" от родителя и он тут же появляется, при выводе курсора из дочернего элемента он снова исчезает, благодаря "наследованной" у родителя onMouseout, а иногда и снова появляется. Более подробно изложен принцип чуть ниже.
Баг с мерцанием/исчезновением наблюдается не всегда и не со всеми элементами.





Суть событий Javascript — Events

Javascript-событие возникает не на элементе, а на объекте window, которое выше body и document. Лишь после некоторых манипуляций оно приходит к элементу, к которому привязана функция-обработчик. Пример #1 и его код:

<html>
<body onclick="op(event)">
<div>
<span>Кликни</span>
</div>
</body>
</html>

При клике по слову "кликни" создается событие в window, которое спускается по дереву, захватывая узлы (capturing):
document -> body -> div -> span
В последнем узле объект события достигает цели (at target) и далее начинает всплывать (bubbling) вверх:
span -> div -> body -> document -> window

При этом вызываются все события, привязанные к этим элементам. В нашем случае вызовется событие body, которое сообщит нам, каким элементом было вызвано событие (объект event хранит ссылку на своего "вызывателя"). Достаточно хорошо объясняет суть пример #2, где каждому узлу привязано событие.

Стоит отметить, что capturing и bubbling выполняются в зависимости от способа привязки события к элементу. Простая привязка через свойство или атрибут onClick выполняет только bubbling, а метод addEventListener(), в зависимости от третьего параметра, выполняет либо capturing (true), либо bubbling (false)



События в Javascript регистрируются по мере обработки. Если функция-обработчик предыдущего события не успела отработать, события не регистрируются.

Это и объясняет тот факт, что пропадает вложенный элемент не всегда. Когда курсор передвигается медленно, события успевают обрабатываться (при выводе курсора из вложенного элемента — onMouseout (bubbling), а за тем — onMouseOver (at target)), если курсор передвигать быстро, то второе событие зарегистрироваться не успеет и элемент пропадет.

Оставить сообщение






Любое копирование должно сопровождаться ссылкой на сайт.
Если вам что-то не понравилось — сообщайте.
Кича Владимир
x
Мне не нравится этот сайт, удалить его