web-dev-qa-db-ja.com

jQuery:blur()イベントの前にclick()を起動する

オートコンプリートの提案をしようとする入力フィールドがあります。コードは次のようになります

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

入力のblur()イベントで、結果のdivを非表示にしたい:

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

入力に何かを書き込むと、サーバーにリクエストを送信してjson応答を取得し、ul-> li構造に解析して、このulを#myresults divに入れます。

この解析されたli要素をクリックすると、liから値を設定して#myresults divを入力および非表示にしたい

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

すべては順調に進んでいますが、クリックするとblur()イベントがclick()の前に発生し、入力の値はliのhtmlを取得しません。

click()の前にblur()イベントを設定するにはどうすればよいですか?

124
Egor Sazanovich

解決策1

mousedownの代わりにclickを聞いてください。

mousedownおよびblurイベントは、マウスボタンを押すと次々に発生しますが、clickはマウスボタンを離したときにのみ発生します。

解決策2

mousedownpreventDefault()でドロップダウンがフォーカスを奪うのをブロックできます。わずかな利点は、マウスボタンを放したときに値が選択されることです。これがネイティブ選択コンポーネントの動作です。 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();
});
287
Alexey Lebedev

私はちょうど同様の質問に答えました: https://stackoverflow.com/a/46676463/227578

Mousedownソリューションの代替策は、特定の要素をクリックすることによって引き起こされるぼかしイベントを無視することです(つまり、ぼかしハンドラーで、特定の要素をクリックした結果である場合、実行をスキップします)。

$("#myinput").live('blur',function(e){
     if (!e.relatedTarget || !$(e.relatedTarget).is("#myresults ul li")) {
         $("#myresults").hide();
     }
});
2
dule
$(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

2
adeneo

私はこの問題に直面し、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');
        });
1
geckob

非ボタン要素をクリックすると、マウスダウンソリューションが機能しません。だから、ここで私は私のコードでぼかし関数でやったことです:

.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;
*/
});
0
Andriy