Как отключить события мыши, вызванные дочерними элементами?

Позвольте мне подробно описать проблему:

Я хочу показать абсолютный позиционированный div при зависании над элементом. Это очень просто с jQuery и работает отлично. Но когда мышь переходит через один из дочерних элементов, она запускает событие mouseout из содержащего div. Как заставить javascript запускать событие mouseout содержащего элемента при зависании дочернего элемента.

Какой лучший и самый короткий способ сделать это с помощью jQuery?

Вот упрощенный пример, иллюстрирующий, что я имею в виду:

Html:

<a>Hover Me</a>
<div>
  <input>Test</input>
  <select>
    <option>Option 1</option>
    <option>Option 2</option>
  </select>
</div>

Javascript/JQuery:

$('a').hover( function() { $(this).next().show() }
              function() { $(this).next().hide() } );

Ответ 1

Вопрос немного старый, но я столкнулся с этим на днях.

Самый простой способ сделать это с помощью последних версий jQuery - использовать события mouseenter и mouseleave, а не mouseover и mouseout.

Вы можете быстро протестировать поведение:

$(".myClass").on( {
   'mouseenter':function() { console.log("enter"); },
   'mouseleave':function() { console.log("leave"); }
});

Ответ 2

Для простоты я просто реорганизовал html немного, чтобы поместить вновь отображаемый контент внутри элемента, связанного с событием mouseover:

<div id="hoverable">
  <a>Hover Me</a>
  <div style="display:none;">
    <input>Test</input>
    <select>
      <option>Option 1</option>
      <option>Option 2</option>
    </select>
  </div>
</div>

Затем вы можете сделать что-то вроде этого:

$('#hoverable').hover( function() { $(this).find("div").show(); },
                       function() { $(this).find("div").hide(); } );

Примечание. Я не рекомендую встроенный css, но это было сделано, чтобы упростить переваривание примера.

Ответ 3

Yeap, ребята, используйте .mouseleave вместо .mouseout:

$('div.sort-selector').mouseleave(function() {
    $(this).hide();
});

Или даже используйте его в комбинации с live:

$('div.sort-selector').live('mouseleave', function() {
    $(this).hide();
});

Ответ 4

Вы ищете jQuery-эквивалент javascript, предотвращающий пузырь событий.

Проверьте это:

http://docs.jquery.com/Events/jQuery.Event#event.stopPropagation.28.29

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

Ответ 5

Я просто проверяю, находятся ли координаты мыши вне элемента в событии mouseout.

Это работает, но для этого достаточно много кода: (

function mouseOut(e)
{
    var pos = GetMousePositionInElement(e, element);
    if (pos.x < 0 || pos.x >= element.size.X || pos.y < 0 || pos.y >= element.size.Y)
    {
        RealMouseOut();
    }
    else
    {
         //Hit a child-element
    }
}

Сокращение кода для удобства чтения не будет работать из коробки.

Ответ 6

Я согласен с Райаном.

Ваша проблема в том, что "следующий" div не является "дочерним" из A. Нет никакого способа для HTML или jQuery знать, что ваш элемент "a" связан с дочерним div в DOM. Обертывание и наложение на обертку означает, что они связаны.

Обратите внимание, что его код не соответствует лучшим практикам. Не устанавливайте скрытый стиль внутри элементов; если пользователь имеет CSS, но не javascript, элемент будет скрыт и не сможет быть показан. Лучшая практика заключается в том, чтобы поместить это объявление в событие document.ready.

Ответ 7

То, как я обычно видел, что это обрабатывается, заключается в задержке около 1/2 секунды между перемещением мыши из элемента HoverMe. При перемещении мыши в наведенный элемент вам нужно установить некоторую переменную, которая сигнализирует о том, что вы нависаете над элементом, а затем в основном остановите зависающую часть от скрытия, если эта переменная установлена. Затем вам нужно добавить аналогичную функцию скрытия OnMouseOut из зависающего элемента, чтобы она исчезла при удалении мыши. Извините, я не могу дать вам какой-либо код или что-то более конкретное, но я надеюсь, что это укажет вам в правильном направлении.

Ответ 8

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

Я хотел бы только указать разницу между mouseover/mouseout и mouseenter/mouseleave. Вы можете прочитать полезное объяснение здесь (зайдите в самую нижнюю часть страницы для рабочей демонстрации). Когда вы используете mouseout, событие останавливается, когда мышь входит в другой элемент, даже если это дочерний элемент. С другой стороны, когда вы используете mouseleave, событие не запускается, когда мышь контролирует дочерний элемент, и это поведение, которое OP хотел бы достичь.

Ответ 9

Я решил эту проблему, добавив pointer-events: none; к моим дочерним элементам css