Javascript: сработало несколько событий мыши - PullRequest
5 голосов
/ 24 апреля 2010

Я знаю о различных моделях событий в Javascript (модель WC3 и модель Microsoft), а также о разнице между пузырями и захватом. Однако, после нескольких часов чтения различных статей по этой проблеме, я все еще не уверен, как правильно кодировать следующее, казалось бы, простое поведение:

Если у меня есть внешний div и внутренний div элемент, я хочу, чтобы одно событие отключения мыши вызывалось, когда мышь покидает внешний div. Когда мышь переходит от внутреннего div к внешнему div, ничего не должно происходить, а когда мышь переходит из external div в inner div, ничего не должно происходить. Событие должно только срабатывать, если мышь перемещается от внешнего элемента к окружающей странице.

<div id="outer" style = "width:20em; height:20em; border:1px solid #F00" align = "center" onmouseout="alert('mouseout event!')" >
<div id="inner" style = "width:18em; height:18em; border:1px solid #000"></div>
</div>

Теперь, если я поместил событие "mouseout" на внешний div, два события mouse-out будут запущены, когда мышь переместится из inner-div на окружающую страницу, потому что событие срабатывает один раз, когда мышь перемещается изнутри наружу, а затем снова, когда она перемещается из наружи на окружающую страницу.

Я знаю, что могу отменить событие, используя ev.stopPropagation(), поэтому я попытался зарегистрировать обработчик событий с помощью внутреннего div, чтобы отменить распространение события. Тем не менее, это не помешает событию сработать, когда мышь переместится из внешнего div во внутренний div.

Так что, если я что-то не замечаю, мне кажется, что такое поведение невозможно осуществить без сложных функций отслеживания мыши. В будущем я планирую переопределить большую часть этого кода, используя более продвинутый фреймворк, такой как JQuery, но сейчас мне интересно, есть ли простой способ реализовать вышеуказанное поведение в обычном JavaScript.

1 Ответ

6 голосов
/ 24 апреля 2010

Событие mouseout на внутреннем элементе «пузыри» для внешнего элемента. Чтобы обнаружить, что это произошло из внешнего div, проверьте свойство target event:

<div id="outer">
    <div id="inner">x</div>
</div>
document.getElementById('outer').onmouseout= function(event) {
    // deal with IE nonsense
    if (event===undefined) event= window.event;
    var target= 'target' in event? event.target : event.srcElement;

    if (target!==this) return;
    ...
};

Обычная проблема с mouseout заключается в том, что вы получаете его, когда указатель перемещается «из» родителя, даже если он только «входит» в дочерний элемент. Вы можете обнаружить этот случай вручную, посмотрев список предков элемента, в который перемещается мышь:

    var other= 'relatedTarget' in event? event.relatedTarget : event.toElement;
    while ((other= other.parentNode).nodeType===1)
        if (other===this) return;

Это модель mousein / mouseout: ее интересует только то, какой элемент является непосредственным родителем мыши. Чаще всего вам нужна модель mouseenter / mouseleave, которая рассматривает деревья элементов как единое целое, поэтому вы получите mouseleave только тогда, когда указатель покидает элемент-или-его-потомки и не перемещается напрямую в элемент-или-его-потомков.

К сожалению, mouseenter / mouseleave в настоящее время является парой событий только для IE. Надеемся, что другие браузеры подберут его, как ожидается, что он станет частью событий DOM уровня 3.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...