Funky jQuery mouseleave Поведение - PullRequest
       12

Funky jQuery mouseleave Поведение

6 голосов
/ 19 января 2010

У меня есть выпадающий контейнер, похожий на меню, который скрывается через привязку события mouseleave.

<div id="container">
<select>
    <option>1</option>
    <option>2</option>
    <option>3</option>
    <option>4</option>
    <option>5</option>
</select>
</div>

Проблема, с которой я сталкиваюсь, состоит в том, что дочерние элементы моего контейнера содержат объект SELECT, где ОПЦИИ SELECT физически выходят за пределы контейнера. Следовательно, при наведении указателя мыши на ОПЦИИ за пределами границ запускается событие "mouseleave", которое вызывает и закрывает мой выпадающий список. SELECT является дочерним элементом контейнера, поэтому в этом случае я ожидаю, что событие mouseleave распознает это.

Ответы [ 5 ]

4 голосов
/ 01 ноября 2012

Очень простое и эффективное решение этой проблемы - контролировать координаты указателя мыши перед выполнением действия.Если контейнер не в фокусе, чтобы сосредоточиться на элементе «выбрать», он проверяет указатель.Если указатель находится внутри контейнера, он не выполняет никаких действий, однако, если это действие элемента контейнера, выполняется

 $('#div_solapa_lateral').bind("mouseenter",function(){
            $(this).animate({left:'0'},500);
        });

    $('#div_solapa_lateral').bind("mouseleave",function(e){
            if ( e.clientX>360 || e.clientY<60 || e.pageY>625 )
            $(this).animate({left:'-320'},500);
        });

clientX и clientY для "position:relative;" pageX и pageY для "position:absolute; "

4 голосов
/ 16 августа 2011

Обновление решения Blocka, поскольку оно некорректно работает с Firefox:

if ((typeof e.fromElement != 'undefined' && !e.fromElement.length) ||
    (typeof e.fromElement == 'undefined' && e.target.tagName != 'SELECT')) {
    // perform your mouseleave logic
}
2 голосов
/ 20 января 2010

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

.bind("mouseleave", function(e) { // ANSWER HERE!!!
    if (!e.fromElement.length) {
        _state.filterTrigger.data("open", false);
        setTimeout(function() { _toggleFilter(_state.filterTrigger); }, 2000);
    }
});

Объект e.fromElement выдает количество объектов OPTION в SELECT. Этот объект не определен для других тегов HTML. Я не пробовал ваше решение, но оно работает и для меня.

1 голос
/ 19 января 2010

Большинство средств визуализации (все, кроме Gecko, я думаю) реализуют открытые <select> меню и их опции в отдельном «окне», а не как элементы на странице. Таким образом, страница не обязательно знает о взаимодействии пользователя с открытым меню <select>. Маловероятно, что вы сможете достичь желаемого эффекта во всех основных браузерах ...

Редактировать: ... но может быть и так. Это работает для меня в Safari и Firefox. Я не могу сейчас тестировать в IE, но попробую:

var timer;
$('#container').mouseleave(function(e) {
    if($(e.target).parents('#container').length) {
        return;
    }
    timer = setTimeout(function() {
        $('#container select').blur();
    }, 50);
}).mouseenter(function(e) {
    if(timer) {
        clearTimeout(timer);
    }
});

Редактировать 2: на самом деле Safari вообще не запускает mouseleave (или mouseout), когда открыто «окно» <select>.

1 голос
/ 19 января 2010

Возможно, когда раскрывающийся список раскрыт, вы можете установить флаг. Снимите флажок, когда элемент выбран. Когда происходит отпуск мышью, не скрывайте меню, если флажок не установлен.

Я всегда нервничаю по поводу взлома событий пользовательского интерфейса до такой степени, поскольку, скорее всего, вы в конечном итоге оставите какой-нибудь браузер где-то в совершенно непригодном для использования состоянии.

...