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, время: 19:57. |