Как отключить события mouseout, запускаемые дочерними элементами? - PullRequest
102 голосов
/ 08 декабря 2008

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

Я хочу показать абсолютное позиционирование 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() } );

Ответы [ 9 ]

204 голосов
/ 24 июля 2009

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

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

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

$(".myClass").on( {
   'mouseenter':function() { console.log("enter"); },
   'mouseleave':function() { console.log("leave"); }
});
18 голосов
/ 08 декабря 2008

Для простоты я бы просто немного реорганизовал 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, но это было сделано для того, чтобы облегчить восприятие примера.

9 голосов
/ 18 сентября 2015

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

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

Или даже использовать его в сочетании с live:

$('div.sort-selector').live('mouseleave', function() {
    $(this).hide();
});
7 голосов
/ 08 декабря 2008

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

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

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

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

3 голосов
/ 08 декабря 2008

Я просто проверяю, находятся ли координаты мыши вне элемента в событии 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
    }
}

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

1 голос
/ 15 ноября 2017

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

1 голос
/ 09 декабря 2008

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

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

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

0 голосов
/ 02 апреля 2013

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

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

0 голосов
/ 08 декабря 2008

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

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