onmouseout и линк
Всем привет. Столкнулся с довольно странной проблемой. Стоит родительский div в котором прописаны события onmouseover и onmouseout. Все работает, но когда наводишь курсор на ссылку внутри этого div'a чего-то срабатывает событие onmouseout хотя ведь курсор все еще в родительском div'e. Как посоветуете решить проблему?
|
используйте события onmouseenter, onmouseleave
<div id="la" style="width: 100px; height: 100px; background: #f00;">
<a href="">test</a>
</div>
<script>
document.getElementById('la').onmouseenter = function() {
this.style.backgroundColor = '#0f0';
}
document.getElementById('la').onmouseleave = function() {
this.style.backgroundColor = '#f00';
}
</script>
|
Читал уже про это http://www.xiper.net/manuals/html/ev...ouseenter.html
Цитата:
читаю про такие жонглирования http://javascript.ru/tutorial/events...rigger:-target |
ну в опере оно тоже работает... так что там на сайте не полная инфа, а в идеале нужно смотреть в других браузерах.
|
а вообще странно что оно не поддерживается другими браузерами кроме ИЕ и Оперы, хотя насчет ФФ ничего не скажу... нет возможности проветить.. Но в хроме точно не пашет.. Хотя в спецификации такие события есть http://www.w3.org/TR/DOM-Level-3-Eve...ype-mouseenter
|
нда уж, что называется осложнили жизнь
|
Цитата:
|
ну а выход лишь один, для браузеров имеющих событие юзай его, а для других пиши костыль. Начало кода примерно такое:
// elem - это элемент на который хочешь повесить событие
if ( "onmouseenter" in elem ) {
// тут код для тех кто его понимает
} else {
// тут для тех кто не понимает пишешь костыль.
}
|
нет, лучше уже просто словить откуда событие пришло. вот пример кода (со страницы на которую я давал линк)
// Обработчик для mouseover
function mouseoverHandler(event) {
event = event || window.event
var relatedTarget = event.relatedTarget || event.fromElement
// для mouseover
// relatedTarget - элемент, с которого пришел курсор мыши
}
// Обработчик для mouseout
function mouseoutHandler(event) {
event = event || window.event
var relTarg = event.relatedTarget || event.toElement
// для mouseout
// relatedTarget - элемент, на который перешел курсор мыши
}
кстати подправить там надо, relTarg во второй функции (комментарий) |
ну дык это и называется костыль
<div id="la" style="width: 100px; height: 100px; background: #f00;">
<a href="">test</a>
</div>
<script>
function onMouseEnter( elem, callback ) {
if ( "onmouseenter" in elem ) {
if ( elem.addEventListener ) {
elem.addEventListener( "mouseenter", callback, false );
} else {
elem.attachEvent( "onmouseenter", callback );
}
} else if ( elem.addEventListener ) {
elem.addEventListener( 'mouseover', function( event ) {
var relTarg = event.relatedTarget;
while( relTarg && relTarg !== elem && ( relTarg = relTarg.parentNode ) ) {}
if ( relTarg !== elem ) {
callback && callback.call( this, event );
}
}, false );
}
}
function onMouseLeave( elem, callback ) {
if ( "onmouseleave" in elem ) {
if ( elem.addEventListener ) {
elem.addEventListener( "mouseleave", callback, false );
} else {
elem.attachEvent( "onmouseleave", callback );
}
} else if ( elem.addEventListener ) {
elem.addEventListener( 'mouseout', function( event ) {
var relTarg = event.relatedTarget;
while( relTarg && relTarg !== elem && ( relTarg = relTarg.parentNode ) ) {}
if ( relTarg !== elem ) {
callback && callback.call( this, event );
}
}, false );
}
}
var elem = document.getElementById('la');
onMouseEnter( elem, function() {
document.body.appendChild(document.createTextNode('over|'));
});
onMouseLeave( elem, function() {
document.body.appendChild(document.createTextNode('out|'));
});
</script>
|
чуть подправил код.
|
хм... пытаюсь разобраться в костыле. можно поподробнее прокомментировать?
|
Цитата:
Цитата:
Цитата:
|
так, я просто запарился уже пол дня париться над этой фигней. смотри, у меня элементы создаются динамически (ну на которые надо ставить эти события).
|
Цитата:
|
Заработало!!! Спасибо тебе, добрый человек!)
|
А то я сам уже ну просто запарился. Учитывая то что я уже весьма устал зря ты такой костыль крупный реализовал, надо было просто основы расписать ну и далее я уже сам бы все сделал :)
В общем вот основа. событие onmouseover
function go_get(event) {
event = event || window.event;
var relatedTarget = event.relatedTarget || event.fromElement;
var elem = document.getElementById("where_is_parent");
while( relatedTarget && relatedTarget !== elem && ( relatedTarget = relatedTarget.parentNode ) ) {}
if ( relatedTarget === elem ) {
return;
}
//...
событие onmouseout
function go_away(event) {
event = event || window.event;
var relTarg = event.relatedTarget || event.toElement;
var elem = document.getElementById("where_is_parent");
while( relTarg && relTarg !== elem && ( relTarg = relTarg.parentNode ) ) {}
if ( relTarg === elem ) {
return;
}
//...
Все остальное - мишура :) |
Цитата:
|
Ну вот зачем тут примешивать onmouseenter и onmouseleave ?? Они не нужны, и без них хорошо, и кода меньше. Тем более еще и динамически назначать события лично мне неудобно, когда можно применить такой простой и четкий подход, сразу при инсерте html кода можно вписать функции для событий onmouseover и onmouseout. Тем более, опять же, работает кроссбраузерно.
|
Цитата:
|
Не вижу смысла не использовать то что есть встроенное в браузер, причем данные события являются стандартными и не использование более быстрых нативных возможносей браузера я считаю глупо.
|
Я бы предложил использовать делегирование и вешать обработчики на родителя (лучше прямо на body)
|
Цитата:
|
Цитата:
<style>
.show {
background: lightgreen;
margin: 40px;
}
.div {
background: lightgrey;
padding: 2px;
}
</style>
<div class="show">show</div>
<div class="div">
<a href="#">link1</a><br>
<a href="#">link2</a><br>
<a href="#">link3</a><br>
</div>
<script>
window.onload = function () {
document.body.onmouseout = function (e) {
e = e || event;
var rt = e.relatedTarget || e.toElement;
var target = e.target || e.srcElement;
if (target.className == 'div' && rt.parentNode.className != 'div') {
target.style.display = 'none';
}
}
document.onmouseover = function (e) {
e = e || event;
var target = e.target || e.srcElement;
if (target.className == 'show') {
target.parentNode.children[1].style.display = 'block';
}
}
}
</script>
|
Цитата:
Чот не наблюдаю эффекта - скорее всего внедрена ссылка вне данного div
<!DOCTYPE>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251" />
<title>Cообщения</title>
</head>
<body align=center>
<script type="text/javascript" src="http://yandex.st/jquery/1.4.4/jquery.min.js"></script>
<style type="text/css">
#LinkInserTium {
text-align:center;
margin:0 auto;
height:100px;
width:100px;
border:1px red solid;
}
#LinkInserTium:hover {
background-color:#0000CC;
}
#LinkInserTium a {
padding:0 4px;
background-color:#F7F7F7;
border:1px red solid;
}
#hover {
display:none;
}
</style>
<div id=LinkInserTium><br />
<a href="/sdfsdf/">ПриветБ</a>
</div>
<span id=hover>Мышь в DIV</span><span id=out>Мышь ушла с Блока</span>
<script type="text/javascript">
$("#LinkInserTium").mouseover(function(){
$("#hover").show();$("#out").hide();
}).mouseout(function(){
$("#hover").hide();$("#out").show();
});
</script>
</body>
</html>
|
Deff,
на таком примере и не заметишь, потому как браузер просто не успевает внести изменения в ДОМ, как снова нужно вернуть обратное, это заметно на таком примере:
<!DOCTYPE>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251" />
<title>Cообщения</title>
</head>
<body align=center>
<script type="text/javascript" src="http://yandex.st/jquery/1.4.4/jquery.min.js"></script>
<style type="text/css">
#LinkInserTium {
text-align:center;
margin:0 auto;
height:100px;
width:100px;
border:1px red solid;
}
#LinkInserTium:hover {
background-color:#0000CC;
}
#LinkInserTium a {
padding:0 4px;
background-color:#F7F7F7;
border:1px red solid;
}
#hover {
display:none;
}
</style>
<div id=LinkInserTium><br />
<a href="/sdfsdf/">ПриветБ</a>
</div>
<span id=hover>Мышь в DIV</span><span id=out>Мышь ушла с Блока</span>
<script type="text/javascript">
$("#LinkInserTium").mouseover(function(){
document.body.appendChild(document.createTextNode('over|'));
}).mouseout(function(){
document.body.appendChild(document.createTextNode('out|'));
});
</script>
</body>
</html>
вот тут при наведении на ссылку сработает out а потом снова over, вот именно в этом промежутке твое решение и не заметно, так как при out просто не успевает отрисоваться, как снова нужно опять отрисовывать over |
devote,
А поставь фон по hover(как у меня) и попробуй выводить и цвет фона ( если сss цвета не меняецо - мож его отслеживать на переходах ? |
<!DOCTYPE>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251" />
<title>Cообщения</title>
</head>
<body align=center>
<script type="text/javascript" src="http://yandex.st/jquery/1.4.4/jquery.min.js"></script>
<style type="text/css">
#LinkInserTium {
text-align:center;
margin:0 auto;
height:100px;
width:100px;
border:1px red solid;
}
#LinkInserTium:hover {
background-color:#0000CC;
}
#LinkInserTium a {
padding:0 4px;
background-color:#F7F7F7;
border:1px red solid;
}
#hover {
display:none;
}
</style>
<div id=LinkInserTium><br />
<a href="/sdfsdf/">ПриветБ</a>
</div>
<span id=hover>Мышь в DIV</span><span id=out>Мышь ушла с Блока</span>
<script type="text/javascript">
$("#LinkInserTium").mouseover(function(){
var a=$(this).css("background-color")
document.body.appendChild(document.createTextNode(a+'over|'));
}).mouseout(function(){
var a=$(this).css("background-color")
document.body.appendChild(document.createTextNode(a+'out|'));
});
</script>
</body>
</html>
Цвет не меняется при данных пертурбациях - так шо он флаг - если цвет тот жа что и при hover - из .mouseout - return false; |
devote,
:) A а вообщем Ти прав .mouseleave/.mouseenter на JQ - работает и в ИЕ
<!DOCTYPE>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251" />
<title>Cообщения</title>
</head>
<body align=center>
<script type="text/javascript" src="http://yandex.st/jquery/1.4.4/jquery.min.js"></script>
<style type="text/css">
#LinkInserTium {
text-align:center;
margin:0 auto;
height:100px;
width:100px;
border:1px red solid;
}
#LinkInserTium:hover {
background-color:#0000CC;
}
#LinkInserTium a {
padding:0 4px;
background-color:#F7F7F7;
border:1px red solid;
}
#hover {
display:none;
}
</style>
<div id=LinkInserTium><br />
<a href="/sdfsdf/">ПриветБ</a>
</div>
<span id=hover>Мышь в DIV</span><span id=out>Мышь ушла с Блока</span>
<script type="text/javascript">
$("#LinkInserTium").mouseenter(function(){
var a=$(this).css("background-color")
document.body.appendChild(document.createTextNode(a+'over|'));
}).mouseleave(function(){
var a=$(this).css("background-color")
document.body.appendChild(document.createTextNode(a+'out|'));
});
</script>
</body>
</html>
|
Deff,
ну теперь понял разницу в событиях? mouseover, mouseout работают совсем не так как mouseenter, mouseleave... И дело совсем не в ощутимости изменения цвета иль еще чего.. а втом что при сожании на mouseenter обработчика, я знаю что оно будет вызвано лишь раз для элемента, и не произайдет делегирования, то есть оно не будет срабатывать если я мышь держу в его приделах даже на дочерних элементах... что не скажешь о событии mouseover, которое будет срабатывать даже если я не уходил с элемента за его пределы, а всего лишь перешел на дочерний элемент, это и есть делегирование.. когда событие родителя срабатывает по цепи захвата/всплытия |
devote,
Да мну вобщем её не забывал - другое дело - что показалась, что задача ошибки внедрения объекта вне div... А далее по накатанной -коли текущий метод и событие в руках - "как исправить" - потом - понято - чо дух противоречия и накатанности - тут ни к чему - (* хотя походу - mouseenter, mouseleave в JQ сгенерили по флагу из mouseover, mouseout - иначе в ИЕ б -7 не работало |
Цитата:
|
devote, потестил в JQ
Работает везде |
Цитата:
|
devote,
Ну через css цвет тож можно эмуляцию сделать (она чуть попроще наверно - там жа любой параметр - можно вснуть по hover |
не спорю, hover это и есть события mouseenter/mouseleave, одно странно почему на уровне JS не реализовал Хром и ФФ этих событий, вот это загадка..
|
Цитата:
|
Цитата:
|
Цитата:
Что, так значит работают эти события? О_о jquery подключена. но тестить сейчас уже неохото, так это она события эти эмулирует или нет? |
Цитата:
|
| Часовой пояс GMT +3, время: 03:53. |