Держать скользящее меню открытым при наведении курсора - PullRequest
0 голосов
/ 06 февраля 2011

Я пытаюсь преобразовать существующую систему меню, загруженную встроенным Javascript, в новый, более эффективный код, используя только jQuery.

У меня есть горизонтальная полоса с изображениями ролловеров. У меня есть скрытое поле на странице, содержащее целочисленное значение. Когда страница загружена, соответствующее меню загружается с «липкой» версией изображения, а все остальные пункты меню меняются местами при входе и выходе мыши. Он был загружен тоннами встроенного Javascript и файла чудовищного Javascript, который было утомительно конвертировать каждый раз, когда я создавал новый сайт.

Я успешно конвертировал все это в jQuery, где мне также удалось отключить щелчок по пункту меню. Теперь я могу просто установить некоторые переменные и легко настроить их для каждого дизайна сайта.

Отлично работает ...

Теперь выходит новый выпуск. Один дизайн содержит несколько выдвижных ящиков под каждым изображением меню. Скользящая анимация обрабатывается внешним файлом JS, а сами ящики меню представляют собой просто DIV, содержащий содержимое, вложенное в контейнер DIV.

Итак, я написал несколько простых вещей для jQuery, которые анимируют DIV и вставляют его и выводят при наведении курсора мыши для изображений меню.

Проблема в том, что я не могу решить проблему перемещения мыши от изображения меню вниз в ящик меню без закрытия ящика. Я понимаю «почему?» ... Я оставляю изображение, которое запускает анимацию, чтобы закрыть ящик, прежде чем я смогу войти внутрь. Если я применяю анимацию наведения к контейнеру ящика, он просто создает зону под меню, которая также запускает анимацию, и я тоже этого не хочу. Кажется, с jQuery все более усложняется. Все это работало нормально с встроенным Javascript ... Вы могли просто переместить свою мышь из изображения в смежный открытый ящик, не вызывая функцию, чтобы закрыть это ... как будто встроенный "ввод мыши" для ящика отменил изображение "мышь покидает".

Есть предложения?

Спасибо вам!


EDIT:

Мне кажется, я решил эту проблему с помощью .stop (true, false) при переходе от изображения в ящик. Это останавливает анимацию до того, как она запустится. Затем то же самое при вводе изображения ДО начала нормальной анимации ... это имеет эффект остановки анимации, вызванной выходом из ящика и ввода изображения, но также ничего не делает при обычном вводе изображения. Еще тестирование, а затем я выложу пример кода.


РЕДАКТИРОВАТЬ # 2:

У меня он работает с "stop ()" и "delay ()" для управления анимацией, но возможно заблокировать открытие ящика, если вы можете вставить в него мышь быстрее, чем требуется, чтобы открыть его. Устанавливается с 150 мс. но прямо сейчас установите 300 мс, чтобы преувеличить проблему.

Соответствующий код размещен здесь ...

jsfiddle.net / qPLVp / 8 /


РЕДАКТИРОВАТЬ # 3:

Благодаря Нейлу, сейчас это работает очень хорошо. При более высокой скорости анимации состояние мыши, которая выходит за рамки меню и входит в ящик, будет минимальным. Но если это произойдет, ящик не закроется, что намного лучше, чем закрытие из-под вашей мыши.

http://jsfiddle.net/elusien/PayFw/8/


РЕДАКТИРОВАТЬ # 4:

Опять же, благодаря Нейлу, это более эффективная версия того же кода ...

http://jsfiddle.net/PayFw/9/

Ответы [ 5 ]

1 голос
/ 09 февраля 2011

Sparky,

Я придумал другой способ делать вещи.По сути, наложение прозрачной маски поверх «кнопки» и «описания» и использование события «mouseleave».

HTML:

<body>
<div id="Container" class="menuContainer" style="position: relative">
<div id="menumask">&nbsp;</div>
<!-- this simulates the menu rollover image -->
<div id="menuitem" style="position:absolute; background-color:#ff00ff; top:10px; width:200px; height:50px; text-align:center;">
    <b>MENU ITEM</b>
</div>

<!-- this is the drawer -->
    <div id="menu" class="menuContent">
        <br/>
        <p>Content of the menu drawer.</p>
        <br/>
        <p>Bla bla bla </p>
        <br/>
        <p>Bla bla bla Bla.</p>
        <br/>
        <p>Bla bla bla Bla bla.</p>
        <br/>
        <p>Bla bla bla Bla bla bla Bla bla.</p>
    </div>

Javascript:

$(document).ready(function() {
    $('#menuitem').bind('mouseenter', enter);
    $('#menumask').bind('mouseleave', leave);

    $('#menu').css({
        height: '500px',
        position: 'absolute',
        paddingTop: '50px',
        width: '200px',
        backgroundColor: '#080',
        zIndex: -1
    }).hide();
    $('#menumask').css({
        height: '550px',
        width: '200px',
        opacity: 0.99,
        position: 'absolute',
        fontSize: '20000px',
        overflow: 'hidden',
        zIndex: 2
    }).hide();

    function enter(){
        $('#menumask').show();
        $('#menu').stop(true,true).animate({height: 500}, 'slow');
    };
    function leave(){
        $('#menumask').hide();
        $('#menu').stop(true,true).slideUp({height:   0}, 'slow');};  
});

Вы можете использовать это в качестве основы для вашей системы меню.

С уважением, Нил

1 голос
/ 07 февраля 2011

Я изменил ваш код jsFiddle, чтобы он работал. По сути, я прикрепил объект данных к вашему элементу #menu. Когда вы открываете этот ящик, объект {opening: true}. Когда ящик полностью открыт (анимация завершена), объект равен {opening: false}. Я проверяю это, когда вы входите в ящик, и если оно ложно, я прекращаю анимацию. Если это правда, я НЕ прекращаю анимацию.

Код:

    function enter(event) { // mouseenter IMG
        // removed image rollover code

        $('#menu').data({opening: true}).stop(true, false).animate({
            top: '0',
            opacity: 1
        },{
            duration: 300  // slow the opening of the drawer
        },
        function(){$(this).data({opening: false});}
        );
    };
    function leave(event) { // mouseout IMG
        // removed image rollover code

        $('#menu').delay(400).animate({
            top: '-'+$ht+'px',
            opacity: 0
        },{
            duration: 600
        });
    };

    $('#menu').hover(
        function (){ // mouseenter Menu drawer
            if (!$(this).data('opening')) {
                $(this).stop(true, false);
            }
        },
        function (){ // mouseout Menu drawer
            $(this).delay(400).animate({
                top: '-'+$ht+'px',
                opacity: 0
            },{
                duration: 600    
            });

       }
   );

Теперь это работает нормально. Вы можете повторить некоторые из ваших «задержек» в свете этого.

0 голосов
/ 30 апреля 2017

Эй, я наткнулся на этот пост, пытаясь сделать то же самое.Я подумал, что могу оставить свое решение, потому что сейчас 2017 год, .delegate устарел, и использование данных для отслеживания того, был ли переход все еще в силе, казалось грязным.

Ключ использовал элемент, переданный вmouseleave обратный вызов для получения element.relatedTarget.

$('.myMouseoverElements').on('mouseover', function() {        

  activeElements = $('.elements.to.open')
  activeElements.addClass('open')

  activeElements.on('mouseleave', function(element) {

    var sustainElements = $('.elements.to.sustain.mouseover')
    var drawerShouldClose = !$(element.relatedTarget).is(sustainElements)

    if (drawerShouldClose) {
      activeElements.removeClass("open")
      activeElements.off("mouseleave")
    }
  })
})

Спасибо за помощь!

0 голосов
/ 07 февраля 2011

Не видя код, трудно понять, сработает ли следующее:

hover() принимает в качестве аргументов 2 функции, первая выполняется при вводе изображения, вторая;когда вы оставляете изображение.

Возможно, вы установили вторую функцию, чтобы скрыть (закрыть) ящик.Я бы добавил небольшую задержку (например, delay(100)) перед hide() и установил событие наведения на самом ящике, чтобы (в первом аргументе функции) остановить очередь анимации stop(true, true) - это остановит закрытие ящика,а во второй функции - закройте ящик, когда выходите из него.

0 голосов
/ 07 февраля 2011

Похоже, вы ищете функцию .delegate (), которая присоединяет обработчик к событию DOM сейчас или в будущем:

$(".menuItem").delegate(".subMenu","hover", function(){ $(this).show(); });

Вы можете прочитать больше о .delegate () функция и ее приятель .live () здесь: http://api.jquery.com/delegate/

...