Модераторы: Sardar, Aliance

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Событие mouseout при наведении мыши на пункт меню 
V
    Опции темы
XEugene
Дата 10.5.2009, 22:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 116
Регистрация: 1.1.2008

Репутация: нет
Всего: 2



Делаю обычное выпадающее меню. При наведении мыши на заголовок меню оно выпадает, при onmouseout убирается.
Проблема в том, что onmouseout возникает при перемещении курсора мыши по выпавшей менюшке, когда курсор наводится на ссылку - пункт меню.  Как с этим бороться?

Код

<html>
<head>
    <style>        
        div.menu ul {padding-top:0; float:right;}
        div.menu ul li {float:left; list-style:none; font-weight:bold; padding-right:15px;  }
        div.menu ul li div.fall { visibility:hidden; background-color:#4682B4; }
    </style>
    <script src="jquery-1.3.2.js"></script>
    <script>
 
            $(document).ready(function() {
 
                var titles = $("div.menu ul li #tab a");
                menuDiv = '';
                for (var i = 0; i < titles.length; i++) {
                    var title = titles[i]; 
                    title.onmouseover = function(e) {
                        if (menuDiv != '') menuDiv.style.visibility = "hidden";
                        var e = e || window.event;  
                        var t = e.target || e.srcElement; 
                        menuDiv = navigator.appName == 'Microsoft Internet Explorer' 
                            ? t.parentNode.parentNode.childNodes[1] : t.parentNode.parentNode.childNodes[2];
                        menuDiv.style.visibility = "visible";
 
                        menuDiv.onmouseout = function(e) {
                            menuDiv.style.visibility = "hidden";
                        }
                     };
                 }
             });
    </script>        
</head>
<body>
<div class="menu"> 
    <ul>
        <li><div id="tab"><a href="">Menu 1</a></div>
            <div class="fall">
                <a href="">item 1</a>
 
                <a href="">item 2</a>
 
                <a href="">item 3</a>
 
            </div>
        </li>
        <li><div id="tab"><a href="/">Menu 2</a></div>
            <div class="fall">
                <a href="">item 1</a>
 
                <a href="">item 2</a>
 
                <a href="">item 3</a>
 
            </div>        
        </li>
        <li><div id="tab"><a href="">Menu 3</a></div>
            <div class="fall">
                <a href="">item 1</a>
 
                <a href="">item 2</a>
 
                <a href="">item 3</a>
 
            </div>        
        </li>
        <li><div id="tab"><a href="">Menu 4</a></div>
            <div class="fall">
                <a href="">item 1</a>
 
                <a href="">item 2</a>
 
                <a href="">item 3</a>
 
            </div>        
        </li>
    </ul> 
</div>
</body>
</html>

PM MAIL   Вверх
Aliance
Дата 12.5.2009, 09:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


I ♥ <script>
****


Профиль
Группа: Модератор
Сообщений: 6418
Регистрация: 2.8.2004
Где: spb

Репутация: 55
Всего: 137



Нужно отлавливать элемент, над которым в текущее время курсор и, если он над текущим подменю, то в зависимости от своих нужд либо прерывать дальнейшую передачу события, либо наоборот. Подробнее читай в моей статье "все о событиях", ссылка в подписи.
PM MAIL WWW ICQ Skype   Вверх
XEugene
Дата 12.5.2009, 22:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 116
Регистрация: 1.1.2008

Репутация: нет
Всего: 2



Или как вариант, определение координат выпавшего подменю и координат курсора в момент возникновения mouseover.
Идея понятна, завтра попробую.

Пока немного подправил скрипт, а то первоначальный вариант страшненький
Код

$(document).ready(function() {

    var titles = $("div.menu ul li #tab a");
    
    for (var i = 0; i < titles.length; i++) {
        var title = titles[i]; 
        title.onmouseover = function(e) {
            var submenus = $("div.menu ul li div.fall");
            for (var j = 0; j < submenus.length; j++) {
                    if (submenus[j].style.visibility == "visible") 
                    submenus[j].style.visibility == "hidden";
            }
            var e = e || window.event;  
            var t = e.target || e.srcElement; 
            var menuDiv = t.parentNode.parentNode.getElementsByTagName('div')[1];
            menuDiv.style.visibility = "visible";
            
            menuDiv.onmouseout = function(e) {
                menuDiv.style.visibility = "hidden";
            }
            
        };
    }
    
});



Это сообщение отредактировал(а) XEugene - 13.5.2009, 08:38
PM MAIL   Вверх
XEugene
Дата 25.5.2009, 20:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 116
Регистрация: 1.1.2008

Репутация: нет
Всего: 2



Вот так я определяю, что mouseover произошло над ссылкой подменю и прерываю всплытие события.
Код

$(document).ready(function() {

    var titles = $("div.menu ul li #tab a");
    
    for (var i = 0; i < titles.length; i++) {
        var title = titles[i]; 
        title.onmouseover = function(e) {
            var submenus = $("div.menu ul li div.fall");
            for (var j = 0; j < submenus.length; j++) {
                    if (submenus[j].style.visibility == "visible") 
                    submenus[j].style.visibility == "hidden";
            }
            var e = e || window.event;  
            var t = e.target || e.srcElement; 
            menuDiv = t.parentNode.parentNode.getElementsByTagName('div')[1];
            menuDiv.style.visibility = "visible";
            menuDiv.style.width = "60px";
            menuDiv.style.height = "80px";
            
            menuDiv.onmouseout = function(e) {
                var e = e || window.event;  
                var t = e.target || e.srcElement; 
                var leftCornerX = pageX(t);
                var rightCornerX = leftCornerX + getWidth(t);
                var topCornerY = pageY(t);
                var bottomCornerY = topCornerY + getHeight(t); 
                var mouseX = getMouseX(e);
                var mouseY = getMouseY(e);
                
                if (mouseX > leftCornerX && mouseX < rightCornerX && mouseY > topCornerY && mouseY < bottomCornerY) {
                    
                    if (!window.event) {
                        e.stopPropagation();
                    }
                    else {
                        window.event.cancelBubble = true;
        
                    }
                }
            

            
                menuDiv.style.visibility = "hidden";
            }
            
        };
    }
    
});

function pageX(elem) {
    return elem.offsetParent ? elem.offsetLeft + pageX(elem.offsetParent) : elem.offsetLeft;
}

function pageY(elem) {
    return elem.offsetParent ? elem.offsetTop + pageY(elem.offsetParent) : elem.offsetTop;
}

function getHeight(elem) {
    return parseInt(elem.style.height);
}

function getWidth(elem) {
    return parseInt(elem.style.width);
}

function getMouseX(e) {
    e = e || window.event;
    return e.pageX || e.clientX + document.body.scrollLeft;
}

function getMouseY(e) {
    e = e || window.event;
    return e.pageY || e.clientY + document.body.scrollTop;            
}

Почему-то не срабатывает код прерывающий всплытие события
Код

if (!window.event) {
    e.stopPropagation();
}
else {
    window.event.cancelBubble = true;
}

PM MAIL   Вверх
Aliance
Дата 25.5.2009, 20:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


I ♥ <script>
****


Профиль
Группа: Модератор
Сообщений: 6418
Регистрация: 2.8.2004
Где: spb

Репутация: 55
Всего: 137



попробуй так:
Код

if ( e.stopPropagation )
    e.stopPropagation();
else
    e.cancelBubble = true;

PM MAIL WWW ICQ Skype   Вверх
XEugene
Дата 25.5.2009, 21:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 116
Регистрация: 1.1.2008

Репутация: нет
Всего: 2



Нет, и так не срабатывает.  Причем во всех браузерах.
PM MAIL   Вверх
Aliance
Дата 25.5.2009, 23:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


I ♥ <script>
****


Профиль
Группа: Модератор
Сообщений: 6418
Регистрация: 2.8.2004
Где: spb

Репутация: 55
Всего: 137



Попробуй замени все
Код

.onmouseout = function(e) {

на
Код

.onmouseout = function() {


Если не поможет, то перед тем кодом, что я писал в предыдущем посте, поставь алерт и проверь - срабатывает ли он вообще.
PM MAIL WWW ICQ Skype   Вверх
XEugene
Дата 26.5.2009, 07:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 116
Регистрация: 1.1.2008

Репутация: нет
Всего: 2



Код

onmouseout = function()
Так в Firefox вообще ничего не происходит(объект события ведь отсутствует), в IE все по-прежнему, то есть работает все кроме остановки всплытия.

Если вернуть function(e)
Код

if ( e.stopPropagation ) { 
    alert('FF');
    e.stopPropagation();
}
else {
    alert('IE');
    e.cancelBubble = true;
}
alert срабатывает и для FF и для IE.  Если не передавать в функцию объект события, то только для IE.
PM MAIL   Вверх
Soah
Дата 26.5.2009, 08:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 512
Регистрация: 18.2.2009

Репутация: 8
Всего: 54



Код

menuDiv.onmouseout = function(evt) {
                evt = evt || window.event;  
                var t = evt.target || evt.srcElement; 
                //...
                
                if (mouseX > leftCornerX && mouseX < rightCornerX && mouseY > topCornerY && mouseY < bottomCornerY) {
                    
                    if (!window.event) {
                        evt.stopPropagation();
                    }
                    else {
                        evt.cancelBubble = true;
        
                    }
                }
                 //...

?
PM MAIL   Вверх
XEugene
Дата 26.5.2009, 23:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 116
Регистрация: 1.1.2008

Репутация: нет
Всего: 2



И так нет.  А чем это отличается от моего варианта,  кроме того, что переменная evt глобальная(зачем?).
PM MAIL   Вверх
Soah
Дата 26.5.2009, 23:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 512
Регистрация: 18.2.2009

Репутация: 8
Всего: 54



Цитата(XEugene @  26.5.2009,  23:08 Найти цитируемый пост)
переменная evt глобальная(зачем?).

?

Код

<script type="text/javascript">
    function foo(evt) {
        evt = evt || window.event; 
        ff();
    }
    
    function ff() {
        alert(evt)
    }
</script>

<input type="button" value="click" onclick="foo(event)" />


и что алертится?
PM MAIL   Вверх
youri
Дата 27.5.2009, 05:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 740
Регистрация: 17.4.2004

Репутация: 2
Всего: 16



1) а почему есть элементы с одинаковым id?
2) при чем тут cancelBubble/stopPropagation?
3) кроме того, cancelBubble/stopPropagation не прерывают выполнение обработчика и "menuDiv.style.visibility = "hidden";" все равно выполняется
4) почему определяются границы target/srcElement, ведь на ссылках подменю тоже возникает mouseover
5) еще надо предусмотреть mouseover для пунктов главного меню
6) а еще можно ведь смотреть к какому элементу переходит мышка (без определения координат)
PM   Вверх
XEugene
Дата 2.6.2009, 19:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 116
Регистрация: 1.1.2008

Репутация: нет
Всего: 2



Цитата(youri @  27.5.2009,  05:54 Найти цитируемый пост)
1) а почему есть элементы с одинаковым id?
2) при чем тут cancelBubble/stopPropagation?
3) кроме того, cancelBubble/stopPropagation не прерывают выполнение обработчика и "menuDiv.style.visibility = "hidden";" все равно выполняется
4) почему определяются границы target/srcElement, ведь на ссылках подменю тоже возникает mouseover
5) еще надо предусмотреть mouseover для пунктов главного меню
6) а еще можно ведь смотреть к какому элементу переходит мышка (без определения координат) 

1)Html скопипастил откуда-то, поправлю.
2)А что же причем, если мне нужно предотвратить всплытие события?
3)В этом и вопрос.  Почему они его не прерывают, если должны?
4)Проверяется, что mouseout возник внутри подменю. А там его могла вызвать только ссылка и это событие нужно придушить.
5) Согласен
6)Искал подобное, но что-то не нашел. Надо поискать еще, буду благодарен за пример или ссылку.

Добавлено через 7 минут и 6 секунд
Soah, у меня переменная содержащая объект события доступна в нужном месте
Код

if (!window.event) {
     alert(evt); //выводит objectMouseEvent
     evt.stopPropagation();
}
else {
      alert(evt); //выводит object
      evt.cancelBubble = true;
}
переменная создана внутри функции и там же используется, зачем ее делать глобальной?
PM MAIL   Вверх
youri
Дата 2.6.2009, 20:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 740
Регистрация: 17.4.2004

Репутация: 2
Всего: 16



Цитата(XEugene @  2.6.2009,  19:44 Найти цитируемый пост)
2)А что же причем, если мне нужно предотвратить всплытие события?

у тебя два обработчика при чем на таких эелментах, что событие не может "всплыть" из одного обработчика в другой
Цитата(XEugene @  2.6.2009,  19:44 Найти цитируемый пост)
3)В этом и вопрос.  Почему они его не прерывают, если должны?

они не должны, он отменяют всплытие события, а выход из функции выполняется с помощью return
Цитата(XEugene @  2.6.2009,  19:44 Найти цитируемый пост)
4)Проверяется, что mouseout возник внутри подменю. А там его могла вызвать только ссылка и это событие нужно придушить.

проверяется, что mouseout произошел внутри target/srcElement, а это вполне может быть ссылка
Цитата(XEugene @  2.6.2009,  19:44 Найти цитируемый пост)
6)Искал подобное, но что-то не нашел. Надо поискать еще, буду благодарен за пример или ссылку.

могу объяснить: при onmouseout target/fromElement - откуда перешла мышка, relatedTarget/toElement - куда... переходить можно с пункта главного меню на его подменю и назад, при остальных переходах нужно скрывать подменю
Цитата(XEugene @  2.6.2009,  19:44 Найти цитируемый пост)
переменная создана внутри функции и там же используется, зачем ее делать глобальной?

переменная не делается глобальной
PM   Вверх
ksnk
Дата 2.6.2009, 23:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


прохожий
****


Профиль
Группа: Комодератор
Сообщений: 6855
Регистрация: 13.4.2007
Где: СПб

Репутация: 84
Всего: 386



Я обще не понимаю, а зачем тут нужна JQuery? На мой взгляд, все фреймворки пытаются скрыть такую убогую магию от программиста. 
Вот так мог бы выглядеть стартовый пример, если бы пользоваться jQuery немного больше.
Код

    $(document).ready(function() {
        var menuDiv = false;
        $("div.menu ul li #tab a").mouseover(function(e) {
            if (menuDiv) 
                menuDiv.css('visibility','hidden');
            menuDiv = $(this).parents('div').eq(0).next('div')
                .css('visibility','visible')
                .mouseout(
                    function(){
                        $(this).css('visibility','hidden')
                    }
                )
        })
    });



--------------------
Человеку свойственно ошибаться, программисту свойственно ошибаться профессионально ! user posted image
PM MAIL WWW Skype   Вверх
Ответ в темуСоздание новой темы Создание опроса
Форум для вопросов, которые имеются в справочниках, но их поиск вызвал затруднения, или для разработчика требуется совет или просьба отыскать ошибку. Напоминаем: 1) чётко формулируйте вопрос, 2) приведите пример того, что уже сделано, 3) укажите явно, нужен работающий пример или подсказка о том, где найти информацию.
 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | JavaScript: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0838 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.