Javascript-форум (https://javascript.ru/forum/)
-   Events/DOM/Window (https://javascript.ru/forum/events/)
-   -   mouseover, mouseout - не распространяется на дочерние элементы (https://javascript.ru/forum/events/1912-mouseover-mouseout-ne-rasprostranyaetsya-na-dochernie-ehlementy.html)

barmaley 04.10.2008 08:35

mouseover, mouseout - не распространяется на дочерние элементы
 
Штука такая:
<div style="display:inline" id="myDiv">Some Text<span style="display:none"><select..></select></div>

Event.observe('myDiv', 'mouseover', this.onIn.bindAsEventListener(this));
Event.observe(this.container, 'mouseout', this.onOut.bindAsEventListener(this));

так вот в чём проблема - при наведении на текст(some text) отрабатывает mouseover - там я показываю внутренний скрытый span. Но когда я мышь увожу на этот select в спане - срабатывает mouseout!! В в3ц вроде пишет, что он mouseover, mouseout распространяется на все дочерние элементы. Собсна хотелось-бы понять, почему так и что происходит. Если событие вешается на все дочерние - то получается отрабатывает mouseout с textNode - some text что-ли?

ZoNT 04.10.2008 10:57

Во-первых ты не закрыл спан, во вторых ты пользуешся фремворком. w3c за фреймворки не отвечает...

barmaley 04.10.2008 11:15

ну спан - это я тут накидал. ща разобрался - и over & out всплывают на всех дочерних. но ёлки, в диве находится селект - я на селект навожу - всплывает mouseout на диве - почему, ведь селект внутри дива. и как отследить уход из div-a и всего его содержимого?

ZoNT 05.10.2008 12:38

в браузерах (в ФФ точно) есть баги: при переходе границы елементов может всплывать аут. Так что надо писать функции с таймером: на аут ставить таймер, а на овер - отменять.

Андрей Параничев 05.10.2008 14:36

ZoNT,
Разве это баги? Это стандартное всплывание события.

barmaley 05.10.2008 16:21

вообщем-то я оставил как есть - при переходе внутри элемента к другому элементу - сначала аут срабатывает и сразу-же over над внутренним элементом - т.е. при движении он прячется и тут-же показывается - вроде не мерцает

ZoNT 05.10.2008 23:40

Цитата:

Сообщение от Андрей Параничев (Сообщение 6688)
ZoNT,
Разве это баги? Это стандартное всплывание события.

естественно баги: если есть див, а в нём элемент поменьше, то при переходе див/элемент (кусор НЕ выходит за пределы дива) происходит мгновенный маусаут+маусовер дива.

verdim 09.07.2010 16:40

Люди !!!! Как хорошо, что я на Вас напал .... У меня происходит примерно такая же фигня:
есть несколько вложенных друг в друга div, два из них наложенные с разными z-index для создания меню. Стоят обработчики события onmouseover и onmouseout. И вот что диагностикой обнаружено:
цвет иконки путем сокрытия иконки меняется (иконки для того, чтобы все было видно нормально при любых условиях);
вначале срабатывает onmouseover (вроде все нормально, - так и должно быть), а затем сразу же срабатывает onmouseout и этим все заканчивается. И еще: не могу поймать разницу между выходом из меню вообще (чтобы закрыть все дочерние окна) и в родительское, чтобы закрыть исходное ....
Будьте добры, разъясните непонятливому (желательно на уровне детского сада) в чем моя ошибка и как ее исправить ...
С уважением, Дмитрий
P.S. Лучше продублировать мне на почту, чтобы всем было хорошо
(мало ли потеряю адрес).

Роман Валерьевич 05.10.2011 15:16

Цитата:

Сообщение от ZoNT (Сообщение 6701)
естественно баги: если есть див, а в нём элемент поменьше, то при переходе див/элемент (кусор НЕ выходит за пределы дива) происходит мгновенный маусаут+маусовер дива.

Цитата:

Сообщение от Андрей Параничев (Сообщение 6688)
ZoNT,
Разве это баги? Это стандартное всплывание события.

Меня этот вопрос тоже интересует. Столкнулся с подобной ситуацией в IE7. Если это всплывание события, то почему оно таким образом проявляется? Почему происходит моментальный вызов с возвратом mouseout, если никакие действия к генерации этого события не приводят.

Я склонен относить подобное поведение к глюку, но хочу разобраться окончательно чтобы точно знать.

dmitriymar 05.10.2011 15:34

это не глюк .дело в том что при вложенных элементах возникает событие оут у родительского при переходе на дочерний. но за счёт того что у вас обработчик на родительском и идёт всплытие -события генерируются в такой последовательности оут-всплытие события-овер.и почему пропускается оут в других браузерах это странно ,объяснение вижу только одно-вложенный контейнер пустой -а при пустых контейнерах событие как бы проваливается в нижний заполненный.и не важно родительский он или просто подложенный.прозрачность ему чуть поменяйте и проваливание отпадёт или бекграунд ему задайте

Роман Валерьевич 05.10.2011 15:46

dmitriymar,
Спасибо за подробное разьяснение!

Leon-on12 07.04.2015 13:02

Рассмотрел всплывающие события подробно. Имея родительский элемент и в нём другой элемент последовательность возникновения событий следующая. 1 - элемент родителя, 2 - вложенный элемент. Out - событие onmouseOUT. Over - событие onmouseOVER.
/////////
out			1
	over		2
	over	1
out				2
out			1
	over	1
/////////

Данная последовательность событий происходит при введении курсора в дочерний элемент и выведении его от туда, при этом не выходя за пределы родительского элемента. И изначально находясь в нём.
Надеюсь это достаточно наглядно. Мне посоветовали воспользоваться stopPropagation(); не разобравшись как он работает я накрутил безумное но действенное решение.
Решение приблизительно такое.

<div id="div1" onmouseover="over1();" onmouseout="out1();setTimeout ('function forDiv1Out()',10)" >
		<div id="div2" onmouseover="over2();" onmouseout="out2();"></div>
</div>

var check = 0;
var check2 = 0;
function out1(){check= 0}
function out2(){check2= 0}
function over1(){check= 1}
function over2(){check2= 1}

function forDiv1Out(){
	if (check==0 && check2==0){
	/*codeHere*/}
};

Но это очень криворуко, так делать не стоит. Если вам нужна функция именно на вывод из родительского дива, то можно потереть функции out2() и over2(). Так же ликвидировать переменную chek2.

mcreature 31.05.2017 12:40

Всем привет!

Тут такое дело, в инете пишут, что mouseenter не учитывает переходы внутри элементов. Но вот у меня почему-то учитывает. Что я могу не правильно делать?

Код самый простой, но работает не как нужно..
$('.mini-basket').on('mouseenter',function() {
		$('.mini-basket-layer').css('visibility', 'visible');
	});

	$('.mini-basket').on('mouseleave',function() {
		$('.mini-basket-layer').css('visibility', 'hidden');
	});

ksa 31.05.2017 13:13

Цитата:

Сообщение от mcreature
Код самый простой, но работает не как нужно..

Ты пример делай полный, а не огрызок JSа...

j0hnik 31.05.2017 13:19

все работает как часы =)
<!DOCTYPE HTML>
<html lang="en">
<head>
	<meta charset="utf-8">
</head>
<body>
<div class="mini-basket" style="display:inline-block; width: 100px; height: 100px; border: 1px solid grey;"></div>
<div class="mini-basket-layer" style="display: inline-block; width: 100px; height: 100px; border: 1px solid grey;"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
	<script>
$('.mini-basket').on('mouseenter',function() {
		$('.mini-basket-layer').css('visibility', 'visible');
	});
	$('.mini-basket').on('mouseleave',function() {
		$('.mini-basket-layer').css('visibility', 'hidden');
	});	
		</script>
	</body>
	</html>

mcreature 31.05.2017 16:05

Цитата:

Сообщение от j0hnik
все работает как часы =)

Как я написал в вопросе, проблема в том, что внутри mini-basket есть еще элементы. mouseenter по идее не должен их учитывать, а он их учитывает и если попадает на внутренний элемент, срабатывает mouseleave.

Ребята, извиняюсь, думал проблема в mouseleave, а проблема оказалась в другом.

Может тогда кто знает, возможно ли сделать так, т.к. мне кажется, что невозможно:
Есть элемент, при наведении на него должен появиться выпадающий блок и layer под ним.
И, соответственно, когда уводишь мышь с этого элемента layer и блок должны исчезнуть.
Собственно проблема в layer, как только он появляется hover и mouseenter спадают.

<!DOCTYPE HTML>
<html lang="en">
<head>
    <meta charset="utf-8">
</head>
<body>
    <div id="site">
        <header id="header">
            <div class="mini-basket" style="width: 100px; height: 100px; border: 1px solid grey;"></div>
        </header>
    </div>
    <div class="layer" style="position: fixed; top: 0; left: 0; width: 100%; height: 100%; z-index: 1; background-color: rgba(0,0,0,0.2); visibility: hidden;"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script>
    $('.mini-basket').on('mouseenter',function() {
        $('.layer').css('visibility', 'visible');
    });
    $('.mini-basket').on('mouseleave',function() {
        $('.layer').css('visibility', 'hidden');
    });
</script>
</body>
</html>

ksa 31.05.2017 16:17

mcreature, где твой пример?
Пока только рассказы... :D

mcreature 31.05.2017 16:45

Цитата:

Сообщение от ksa
mcreature, где твой пример?
Пока только рассказы...

Исправил сообщение выше, там пример.

ksa 31.05.2017 16:53

Цитата:

Сообщение от mcreature
Исправил сообщение выше, там пример.

У j0hnik пример понятен, а твой чего-то нет. :(

Что ты ожидаешь получить в своем примере? И чего не получаешь?

j0hnik 31.05.2017 16:57

z-index: -1 и все заиграет!

ksa 31.05.2017 16:58

Цитата:

Сообщение от mcreature
в инете пишут, что mouseenter не учитывает переходы внутри элементов

Х/з где ты это прочитал... Но у нас про такое не писали...
https://learn.javascript.ru/mousemov...потомка

mcreature 31.05.2017 17:00

Цитата:

Сообщение от ksa
Что ты ожидаешь получить в своем примере? И чего не получаешь?

Над примером я описал ситуацию.
Самое главное: собственно проблема в layer, как только он появляется hover и mouseenter с элемента спадают.

j0hnik, тогда элемент будет над layer, что не годится.

ksa, как раз там и написано.
"Не учитываются переходы внутри элемента."

j0hnik 31.05.2017 17:03

значит вешайте и на layer те же события!

mcreature 31.05.2017 17:19

Цитата:

Сообщение от j0hnik
значит вешайте и на layer те же события!

Как Вы себе это представляете?

j0hnik 31.05.2017 18:14

$('.mini-basket, .layer ')как-то так

mcreature 31.05.2017 18:32

Цитата:

Сообщение от j0hnik
$('.mini-basket, .layer ')как-то так

Тогда получится вечный mouseenter

j0hnik 31.05.2017 18:43

Цитата:

Сообщение от mcreature (Сообщение 454033)
Тогда получится вечный mouseenter

сделайте прозрачный блок и расположите его там где баскет с большим z-index.

j0hnik 31.05.2017 18:46

этот .layer типа оверлея? тогда сделайте его псевдоэлементом

или сделайте нормальный пример чтобы было понятно!

mcreature 31.05.2017 20:51

Цитата:

Сообщение от j0hnik
этот .layer типа оверлея? тогда сделайте его псевдоэлементом

или сделайте нормальный пример чтобы было понятно!

Да, это оверлей (надо было сразу так сказать, извиняйте).
Т.е. при наведении на корзину должен появиться оверлей и поверх него выпадающий блок.

Ссылка в личке.

j0hnik 31.05.2017 21:09

Цитата:

Сообщение от mcreature (Сообщение 454048)
Да, это оверлей (надо было сразу так сказать, извиняйте).
Т.е. при наведении на корзину должен появиться оверлей и поверх него выпадающий блок.

Ссылка в личке.

Ответил в личку у корзины z-index добавить и мигать перестанет!

mcreature 31.05.2017 21:46

Цитата:

Сообщение от j0hnik
Ответил в личку у корзины z-index добавить и мигать перестанет!

Вообще, это не идеальное решение, т.к. корзина получается сверху оверлея. Но при background-color: rgba(0,0,0,0.2) в принципе это не сильно видно. Так что может быть и прокатит.

В любом случае спасибо.

ksa 01.06.2017 08:52

Цитата:

Сообщение от mcreature
как раз там и написано.
"Не учитываются переходы внутри элемента."

И таки работает на 100%! :D

Вот пример.

<!DOCTYPE html>
<html>
<head>
<meta http-equiv='Content-Type' content='text/html; charset=windows-1251' />
<script src='https://code.jquery.com/jquery-latest.js'></script>
<!--
<script src="https://code.angularjs.org/1.3.9/angular.min.js"></script>
<script src="https://code.angularjs.org/1.3.9/angular-route.js"></script>
-->
<style type='text/css'>
#box {
	width: 100px;
	height: 100px;
	display: flex;
	justify-content: center;
	align-items: center;
	background-color: blue;
}
#test {
	width: 50%;
	height: 50%;
	background-color: red;
}
.off {
	display: none;
}
</style>
<script type='text/javascript'>
$(function(){
$('#box').on('mouseenter',function() {
		$('#on').show();
		$('#off').hide();
	}).on('mouseleave',function() {
		$('#off').show();
		$('#on').hide();
	});	
});
</script>
</head>
<body>
<div id='box'>
	<div id='test'></div>
</div>
<div id='on' class='off'>On</div>
<div id='off' class='off'>Off</div>
</body>
</html>

Ни чего не теряется и не пропадает...


Часовой пояс GMT +3, время: 17:45.