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



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Для простоты я бы просто немного реорганизовал 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, но это было сделано для облегчения восприятия примера.
Это действительно очень простое и понятное решение. Спасибо за напоминание. Но в моей конкретной ситуации, которая не совсем такая, как в вопросе, это не вариант. Спасибо хоть!
Попробовав разные методы, описанные другими здесь, в SO, я вернулся к вашему методу и заставил его работать в моем случае. Ура! :-)
Обычно я видел, как это обрабатывается с задержкой около 1/2 секунды между перемещением мыши от элемента HoverMe. При перемещении мыши в элемент, на который наведен курсор, вам нужно установить некоторую переменную, которая сигнализирует, что вы наводите курсор на элемент, а затем, в основном, не позволяла скрывать элемент, на который наведен курсор, если эта переменная установлена. Затем вам нужно добавить аналогичную функцию скрытия OnMouseOut из зависшего элемента, чтобы он исчезал при удалении мыши. Извините, я не могу дать вам код или что-то более конкретное, но я надеюсь, что это укажет вам правильное направление.
Да, idd, я только что реализовал подобное решение. Это действительно распространенная проблема. Мне действительно любопытно, какие еще есть решения ... Спасибо за ответ!
Я просто проверяю, находятся ли координаты мыши вне элемента в событии 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
}
}
Код урезан для удобочитаемости, из коробки не получится.
Вы ищете jQuery-эквивалент javascript для предотвращения всплытия событий.
Проверь это:
http://docs.jquery.com/Events/jQuery.Event#event.stopPropagation.28.29
В основном вам нужно поймать событие в дочерних узлах DOM, и на этом остановить их распространение вверх по дереву DOM. Другой способ, хотя на самом деле он не предлагается (поскольку он может серьезно повредить существующим событиям на вашей странице), - это установить захват событий для определенного элемента на странице, и он будет получать все события. Это полезно для поведения DnD и тому подобного, но определенно не для вашего случая.
это работает так, как должно, не знаю, почему у вас не получилось заставить его работать ... просто информация, ссылка на документы изменилась, новая ссылка - docs.jquery.com/Events/jQuery.Event#event.stopPropagation.28 .29
Я согласен с Райаном.
Ваша проблема в том, что «следующий» div не является «дочерним» для A. HTML или jQuery не могут знать, что ваш элемент «a» связан с дочерним div в DOM. Их упаковка и наведение указателя мыши на оболочку означает, что они связаны.
Обратите внимание, что его код не соответствует лучшим практикам. Не устанавливайте скрытый стиль встроенным в элементы; если у пользователя есть CSS, но нет javascript, элемент будет скрыт и его нельзя будет отобразить. Лучше поместить это объявление в событие document.ready.
Я полностью согласен с добавлением скрытия в событие document.ready. Встроенный CSS должен был просто передать полный рабочий пример самым простым способом. Я отредактирую свой ответ, чтобы прояснить это.
Вопрос немного устарел, но я столкнулся с этим на днях.
Самый простой способ сделать это с последними версиями jQuery - использовать события mouseenter и mouseleave, а не mouseover и mouseout.
Вы можете быстро проверить поведение с помощью:
$(".myClass").on( {
'mouseenter':function() { console.info("enter"); },
'mouseleave':function() { console.info("leave"); }
});
Помогла моя проблема, связанная с javascript, не связанная с jquery. Я использовал mouseenter / mouseout вместо mouseleave с моими слушателями событий!
Для целей поиска это поведение событий мыши эквивалентно ROLL_OVER и ROLL_OUT в AS3.
Избавило меня от головной боли. Странно, как при наведении курсора на дочерние элементы запускается родительское событие mouseout, хотя на самом деле оно все еще находится внутри родительского элемента.
Это старый вопрос, но он никогда не устареет. Правильный ответ должен быть дан Bytebrite.
Я только хотел бы указать на разницу между mouseover / mouseout и mouseenter / mouseleave. Вы можете прочитать отличное и полезное объяснение здесь (перейдите в самый низ страницы, чтобы увидеть рабочую демонстрацию). Когда вы используете mouseout, событие останавливается, когда мышь входит в другой элемент, даже если это дочерний элемент. С другой стороны, когда вы используете mouseleave, событие не запускается, когда указатель мыши наведен на дочерний элемент, и это именно то поведение, которого OP хотел бы достичь.
Ага, ребята, используйте .mouseleave вместо .mouseout:
$('div.sort-selector').mouseleave(function() {
$(this).hide();
});
Или даже используйте его в сочетании с live:
$('div.sort-selector').live('mouseleave', function() {
$(this).hide();
});
Я решил эту проблему, добавив pointer-events: none; в мои дочерние элементы css
Это действительно очень помогло при исправлении устаревшего кода, создающего собственные всплывающие окна с событиями mouseover и mouseleave.