JQuery: пожарный щелчок() перед размытием()

У меня есть поле ввода, где я пытаюсь сделать предложение автозаполнения. Код выглядит как

<input type="text" id="myinput">
<div id="myresults"></div>

На входе blur() событие я хочу скрыть результаты div:

$("#myinput").live('blur',function(){
     $("#myresults").hide();
});

Когда я что-то пишу в свой ввод, я отправляю запрос на сервер и получаю ответ json, анализирую его на структуру ul- > li и помещаю эту ul в div #myresults.

Когда я нажимаю на этот элемент parsed li, я хочу установить значение из li для ввода и скрыть #myresults div

$("#myresults ul li").live('click',function(){
     $("#myinput").val($(this).html());
     $("#myresults").hide();
});

Все идет хорошо, но когда я нажимаю на событие li blur() перед click(), а входное значение не получает li html.

Как настроить событие click() до blur()?

Ответ 1

Решение 1

Слушайте mousedown вместо click.

События mousedown и blur происходят один за другим, когда вы нажимаете кнопку мыши, но click возникает только при ее отпускании.

Решение 2

Вы можете preventDefault() в mousedown заблокировать раскрывающийся список от кражи фокуса. Небольшое преимущество заключается в том, что значение будет выбрано, когда кнопка мыши будет отпущена, а именно, как работают компоненты нативного выбора. JSFiddle

$('input').on('focus', function() {
    $('ul').show();
}).on('blur', function() {
    $('ul').hide();
});

$('ul').on('mousedown', function(event) {
    event.preventDefault();
}).on('click', 'li', function() {
    $('input').val(this.textContent).blur();
});

Ответ 2

$(document).on('blur', "#myinput", hideResult);

$(document).on('mousedown', "#myresults ul li", function(){
     $(document).off('blur', "#myinput", hideResult); //unbind the handler before updating value
     $("#myinput").val($(this).html()).blur(); //make sure it does not have focus anymore
     hideResult(); 
     $(document).on('blur', "#myinput", hideResult);  //rebind the handler if needed
});

function hideResult() {
     $("#myresults").hide();
}

FIDDLE

Ответ 3

Решения Mousedown не работают для меня, когда я нажимаю на элементы без кнопок. Итак, вот что я сделал с функцией размытия в моем коде:

.on("blur",":text,:checkbox,:radio,select",function() {
/*
* el.container 
* container, you want detect click function on.
*/
            var outerDir = el.container.find(':hover').last();
            if (outerDir.length) {
                if ($.inArray(outerDir.prop('tagName'), ["A","SELECT"] ) != -1 || outerDir.prop('type') == 'button' || outerDir.prop('type') == 'submit') {
                    outerDir.click();
                }
                if (outerDir.prop('type') == 'checkbox') {
                    outerDir.change();
                }
                return false;
            }
/*          
* YOUR_BLUR_FUNCTION_HERE;
*/
});

Ответ 4

Я столкнулся с этой проблемой, и использование mousedown для меня не вариант.

Я решил это, используя setTimeout в функции обработчика

        elem1.on('blur',function(e) {

            var obj = $(this);

            // Delay to allow click to execute
            setTimeout(function () {
                if (e.type == 'blur') {

                  // Do stuff here

                }
            }, 250);
        });

        elem2.click( function() {
            console.log('Clicked');
        });

Ответ 5

Я просто ответил на аналогичный вопрос: fooobar.com/info/60389/...

Альтернативой решениям mousedown является игнорирование событий размытия, вызванных щелчком определенных элементов (т.е. в вашем обработчике размытия, пропустить выполнение, если это результат нажатия на определенный элемент).

$("#myinput").live('blur',function(e){
     if (!e.relatedTarget || !$(e.relatedTarget).is("#myresults ul li")) {
         $("#myresults").hide();
     }
});