onmouseenter, onmouseleave vs onmouseover, onmouseout

kruzer25

Чем первые отличаются от вторых, кроме того, что вторые входят в стандарт?

artimon

Трудно посмотреть в документацию?
Первые два не всплывают (bubble).
http://msdn2.microsoft.com/en-us/library/ms536945.aspx

kruzer25

А что это значит?

artimon

Unlike the onmouseover event, the onmouseenter event does not bubble. In other words, the onmouseenter event does not fire when the user moves the mouse pointer over elements contained by the object, whereas onmouseover does fire.
google js event bubbling

kruzer25

ОК, понятно.
А onmouseout так и должен не работать в опере? :shocked:

artimon

Вообще-то всегда работал

hwh2010

У меня вполне работают (плюсики-минусики появляются-исчезают). Opera 9.21.
А вот leave и enter как раз отсутствуют не только в стандартах, но и в большинстве реализаций.

kruzer25

Да, действительно, рано начал паниковать, минимальный пример работает.
Проблема появляется, когда вешаем onmouseover и onmouseout на span, и в обработчике этого onmouseover меняем содержимое span-а с помощью изменения innerHTML.
Тогда все остальные браузеры (точнее, ИЕ и ФФ) ведут себя так, как ожидается (наводим мышь на span - загорается onmouseover, убираем мышь - загорается onmouseout. А в опере - onmouseover загорается и при движении мышью по элементу, а onmouseout не загорается вообще.
Что с этим делать?
вот leave и enter как раз отсутствуют не только в стандартах, но и в большинстве реализаций
Вроде как, оно вообще присутствует только в ИЕ ;)

kruzer25

<span id="opener"
onMouseOver="document.getElementById('debug').innerHTML += 'i';document.getElementById('opener').innerHTML = 'test'"
onMouseOut="document.getElementById('debug').innerHTML += 'o'">test</span>
<span id="debug"></span>

sbs-66

appendChild не учили в детстве юзать? После изменения innerHTML DOM вообще не обязан работать

kruzer25

appendChild добавляет новый элемент, а мне надо поменять текст существующего.
Как это можно сделать прилично?
UPD: Да, если менять не innerHTML, а innerText - в опере по-прежнему те же глюки.

dedwowan

createTextNode

kruzer25

А что дальше делать?
replaceNode - в той же опере содержимое элемента не меняет (вот в этом коде:
<SCRIPT>
function fnChangeNode{
var oTextNode = document.createTextNode("New Text");
var oReplaceNode = oSpan.childNodes(0);
oReplaceNode.replaceNode(oTextNode);
}
</SCRIPT>

<SPAN ID="oSpan" onclick="fnChangeNode">
Original Text
</SPAN>
)
UPD: И, как выяснилось, replaceNode - чисто ИЕшная фишка...

hwh2010


<span id="spn"
onmouseover="document.getElementById('spn').childNodes.item(0).data='over';"
onmouseout="document.getElementById('spn').childNodes.item(0).data='out';"
>original</span>

Тестил в IE6, Opera9, Firefox2
Коллеги, не верьте MSDN, ни developer.mozilla.org (тем более странно это делать, если проблемы с Opera).
Читайте стандарт!
А потОм уже ставьте заплатки для кривых браузеров, если что-то не пашет.

kruzer25

ОК, уговорил, твой вариант действительно работает и в ие, и в фф, и в опере.
А с html-entities что делать?

hwh2010

ОК, уговорил, твой вариант действительно работает и в ие, и в фф, и в опере.
А сила его в том, что с большой долей вероятности он будет работать в сафари, в конкверрере и в чёрте лысом даже после моей смерти и выхода IE8.
Я не понимаю в чём проблема. Если не сложно, расскажи ещё раз.

<span id="spn"
onmouseover="document.getElementById('spn').childNodes.item(0).data='&copy;';"
onmouseout="document.getElementById('spn').childNodes.item(0).data='&quot;';"
>&pi;</span>

Работает

kruzer25

<span id="spn"
onmouseover="document.getElementById('spn').childNodes.item(0).data='&copy;';"
onmouseout="document.getElementById('spn').childNodes.item(0).data='&quot;';"
>&pi;</span>
Как минимум, в ИЕ выведется не значок копирайта, а &copy;
Хрен с ним, эта проблема уже решена, туда можно простой unicode напихать.
Сейчас есть другая проблема, и опять с оперой :mad:

<div
onMouseOver="this.style.borderColor='red'"
onMouseOut="if(event.srcElement == this) this.style.borderColor='green'"
style="padding:15px;border:solid 2px green">
<div style="border:solid 2px black">div1</div>
<div style="border:solid 2px black">div2</div>
</div>

Если мышку навести на div1 - большая рамка, как и положено, загорится красным.
Если мышку медленно вывести за большую рамку - она перекрасится в зелёный.
А если быстро убрать - то останется красной - видимо, потому что курсор уезжает за пределы внешнего дива как раз, пока опера обрабатывает этот всплывающий onMouseOut для внутреннего дива.
В данном случае, можно тупо обойтись без проверки в onMouseOut. А если в onMouseOut надо будет скрыть внешний див? Тогда - тоже, в каких-то браузерах всё будет ОК (пока обрабатывали onMouseOut и скрывали внешний див, уже сработал onmouseover, можно этот див показать); а в некоторых - жопа (быстро обработали onMouseOut, скрыли внешний див, и никакой onmouseover уже не происходит).
Можно ли как-нибудь бороться с этим "всплыванием"? :mad:

dedwowan

Блин. Создай их явно, руками напиши нужный спан/див. Сделай дисплай: ноне и напиши функцию, которая при наведении берет нужный тебе кусок объектной модели и прикрепляет его к нужному тебе контейнеру. Будет у тебя что-то типа
<div id="cont">
<div id="a1">тут идет много разного хтмл кода</div>
</div>
<div id="a2" style display: none>тут идет много другого хтмл кода</div>
и вызываться будет что-то типа
${cont}.replaceChild(${a1}, ${a2});
showElement('a2');
Да, код в таком виде естественно работать не будет, т.к. писать кучу гетэлементбайид меня ломало, а функцию шоуэлемент сперва надо написать.

kruzer25

Это ты к чему?
Вопрос сейчас в том, как прилично сделать, если хочется убирать большой див, когда мы убираем с него курсор.
Мне в голову приходят только два варианта обработки onMouseOut, в одном из них в некоторых браузерах не будет убираться большой див, когда мы быстро убираем мышку с внутреннего дива за границы большого дива; в другом - в некоторых браузерах большой див будет убираться и тогда, когда мы всего лишь убираем курсор с внутреннего дива.

dedwowan

Это к предыдущему вопросу
По теме этого - попробуй поиграться с сеттаймоутом. Т.е. создавай искуственные мини-задержки по времени.

kruzer25

А, ясно.
Нет, html-кода там не будет, конечно, такие вещи не делаются через innerHTML. Там просто есть html-entities, которые, как оказалось, можно в ОS просто запихать в строку в unicode, вне зависимости от используемой кодировки.

kruzer25

Да ну в жопу ваш джаваскрипт, сделаю по-человечески на CSS.

dedwowan

Хм, если ты что-то можешь сделать без написания скриптов - сделай. Скрипты - это предпоследний рубеж обороны :grin:

pilot

И как же? :smirk:

kruzer25

Бля, совсем не подумал о соседнем треде (:hover в ИЕ6)
В общем, если кому интересно, труъ выпадающие меню можно сделать так:
<style>
.onecrumb { position:relative;height:20pt; }
.onecrumb .dropDown { display:none;background-color:white; }
.onecrumb:hover .dropDown, .onecrumb_hover .dropDown { display:block; }
.dropDown { position:absolute;top:20pt; }
</style>
<div class="onecrumb"
onMouseEnter="this.className = 'onecrumb onecrumb_hover'"
onMouseLeave="this.className = 'onecrumb'">
<div>Заголовок</div>
<div class="dropDown">выпадающее меню
выпадающее меню
выпадающее меню
выпадающее меню
выпадающее меню
выпадающее меню
выпадающее меню
выпадающее меню
выпадающее меню
выпадающее меню
выпадающее меню</div>
</div>
что-то ещё что-то ещё
что-то ещё что-то ещё
что-то ещё что-то ещё
что-то ещё что-то ещё
что-то ещё что-то ещё
что-то ещё что-то ещё
что-то ещё что-то ещё
что-то ещё что-то ещё
что-то ещё что-то ещё
что-то ещё что-то ещё
что-то ещё что-то ещё
что-то ещё что-то ещё
что-то ещё что-то ещё
что-то ещё что-то ещё
что-то ещё что-то ещё
что-то ещё что-то ещё

Хорошие браузеры (в том числе и ИЕ7) корректно обрабатывают :hover, и показывают при наведении на "Заголовок" выпадающее меню, которое пропадает только тогда, когда курсор мышки уводят и с заголовка, и с выпадающего меню (чтобы снялся :hover с .onecrumb).
ИЕ 5.5 и выше отловит onmouseenter и onmouseleave (которые не всплывают - т.е. нет геморроя с обработкой соответствующих событий на те блоки, которые могут лежать в .dropDown и применит к внешнему div-у стиль .onecrumb_hover, который ведёт себя, как .onecrumb:hover.
Не самое хорошее решение, конечно - хотелось бы обойтись без всего этого шаманства с завязками на чисто браузерные фишки... но уж получше, чем тот джаваскрипт, который тут выходил.
Почему никто не делает так, а все делают как-то через жопу, с применением ещё более адских джаваскриптов, чем тут у меня начали получаться - хз.

pilot

Почему никто не делает так
Я "делал так" 2 года назад.
Но только ты попробуй быстро по div'у поводить мышой и увидишь что глюки.

kruzer25

А что ты имеешь в виду? Какой именно див и какой браузер?

kruzer25

Ещё одна хрень с мышами.
Если после этого выпадающего div-а определён объект с position:relative (и этот объект оказывается на месте части содержимого div-а считается, что объект с position:relative выше, и, когда мышка проходит по тому месту, где такой объект - происходит onmouseout с div-а, :hover пропадает; если сделать на объект с position:relative рамку, она окажется сверху div-а.
Если выпадающему div-у сделать z-index:1, то всё лечится, рамка оказывается снизу... везде, кроме ИЕ. А в ИЕ что делать?

kruzer25

Бля, оно сожрёт мой мозг :crazy:
Почему в ИЕ видно на красном фоне строку 2 и строку 3 (при этом, строка 1 и "что-то ещё" не видны)?
<html>
<head>
<style>
.onecrumb { position:relative; }
.onecrumb_text { position:relative;z-index:-100; }
.onecrumb .dropDownContainer { position:absolute; z-index:100; left:0px; background-color:red; }
</style>
</head>
<body>

<div class="onecrumb">
<span class="onecrumb_text">Строка 1 Строка 1 Строка 1 Строка 1 Строка 1 Строка 1 Строка 1 </span>
<div class="dropDownContainer">
<div>Пункт 1</div>
<div>Пункт 2</div>
<div>Пункт 3</div>
<div>Пункт 4</div>
<div>Пункт 5</div>
</div>
</div>

<div class="onecrumb">
<span class="onecrumb_text">Строка 2 Строка 2 Строка 2 Строка 2 Строка 2 Строка 2 Строка 2 </span>
</div>

<div class="onecrumb">
<span class="onecrumb_text">Строка 3 Строка 3 Строка 3 Строка 3 Строка 3 Строка 3 Строка 3 </span>
</div>
<div>Что-то ещё Что-то ещё Что-то ещё Что-то ещё Что-то ещё Что-то ещё
Что-то ещё Что-то ещё Что-то ещё Что-то ещё Что-то ещё Что-то ещё
Что-то ещё Что-то ещё Что-то ещё Что-то ещё Что-то ещё Что-то ещё
Что-то ещё Что-то ещё Что-то ещё Что-то ещё Что-то ещё Что-то ещё
Что-то ещё Что-то ещё Что-то ещё Что-то ещё Что-то ещё Что-то ещё
Что-то ещё Что-то ещё </div>
</body>
</html>

kruzer25

ап :crazy:

pilot

JS работает не мгновенно.
Может на одном диве такого и не будет, но на нескольких — будут теряться события.
В FF & Opera & IE 6 (насколько помню). Вряд ли в пятом лучше

kruzer25

JS работает не мгновенно.
Может на одном диве такого и не будет, но на нескольких — будут теряться события.
В FF & Opera
Ну так у меня JS-то сейчас только для ИЕ :)
В ИЕ6, вроде, ничего не теряется.
Всё-таки, как решить проблему, которая вумя постами выше?

kruzer25

Пиздец.
Оказывается, для того, чтобы решить эту проблему - надо, чтобы у каждого следующего элемента с position:relative был z-index ниже, чем у предыдущего.
Соответственно, если в примере выше поставить у первого onecrumb z-index:2, а у второго z-index:1, то всё будет заебись.
Оставить комментарий
Имя или ник:
Комментарий: