jQuery:在blur()事件之前触发click()


134

我有一个输入字段,在这里我尝试提出自动完成建议。代码看起来像

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

在输入blur()事件中,我想隐藏结果的div:

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

当我在输入中写入内容时,我向服务器发送请求并获得json响应,将其解析为ul-> li结构并将此ul放入我的#myresultsdiv中。

当我单击此已解析的li元素时,我想将li的值设置为input并隐藏#myresultsdiv

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

一切都很好,但是当我单击我的li blur()事件之前会触发click()并且输入的值不会得到li的html。

我怎样才能设置click()活动blur()


那么这种情况下为什么要使用模糊功能呢?点击功能已满足您的需求时。
奥怀斯·伊克巴尔

这可能不会改变事件触发的顺序,但是如果blur在单击之后确实触发事件li,则可能不需要$("#myresults").hide()在单击处理程序中执行。似乎正在发生的事情$(this).html()是返回一个空字符串。你能log还是alert $(this).html()要确定?
veeTrain,2012年

@OwaisIqbal有时没有结果,有时用户不想从建议中选择任何内容,有时用户不想再使用此输入,但是我必须隐藏未使用的结果
Egor Sazanovich

@veeTrain处理程序中有许多操作,我只是将它们最小化以方便理解问题中的问题。ps我试图在萤火虫blur()click()处理程序中添加监视点,blur()结束后没有任何操作
Egor Sazanovich 2012年

看来您需要对功能进行排队。尝试查看此页面:stackoverflow.com/questions/1058158/…。先进先出(FIFO)部分可能与您有关
Patriotec

Answers:


312

解决方案1

mousedown而不是click

mousedownblur当您按下鼠标按钮事件接二连三发生,但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();
});

12
解决方案1在这种情况下对我有用!轻松改变!谢谢:)
乔恩(Jon)

谢谢:)但是,您能解释一下为什么听鼠标按下而不是单击会产生魅力吗?
Mudassir Ali 2014年

3
@MudassirAli,因为mousedown事件在模糊之前发生,而click在之后发生。jsfiddle.net/f3BKP
Alexey Lebedev

我认为解决方案1是更好的选择。简单有效。超时将意味着更多的代码+更多的空间来应对意外行为(超时时间多长?足以注册点击次数,但又不会太长以至于混淆使用...)。
cw24 2014年

5
解决方案2巧妙。我永远都不会想出来!谢谢
Tobia

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();
}

小提琴


2

我遇到了这个问题,使用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');
        });

2

我刚刚回答了一个类似的问题:https : //stackoverflow.com/a/46676463/227578

mousedown解决方案的替代方法是忽略单击特定元素引起的模糊事件(即,在模糊处理程序中,如果是单击特定元素的结果,则跳过执行)。

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

就我而言,event.relatedTarget返回null,为什么会这样呢?
gaurav5430 '19


0

当我单击非按钮元素时,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;
*/
});
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.