javascript 模糊操作,除非使用 jQuery 单击特定元素

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4901899/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-25 15:17:11  来源:igfitidea点击:

Action on blur except when specific element clicked with jQuery

javascriptjquery

提问by Justin Stayton

There are two elements in play:

有两个要素在起作用:

$('#myInput') // an input field for search
$('#myList') // a list to display search results

I want to hide the list when the input no longer has focus, like so:

当输入不再具有焦点时,我想隐藏列表,如下所示:

$('#myInput').blur(function() {
  $('#myList').hide();
});

This works great, except when a list item is clicked, because the blur event fires and hides the list before the click is registered. The goal is for the list to stay visible when any part of the list is clicked, even though this will cause the input to blur.

这很好用,除非单击列表项,因为在单击注册之前模糊事件会触发并隐藏列表。目标是在单击列表的任何部分时列表保持可见,即使这会导致输入模糊。

How can I do this? Thanks!

我怎样才能做到这一点?谢谢!

采纳答案by The Scrum Meister

You can accomplish this by keeping a global variable, and setTimouts, to wait a delay of 200ms and then check if one of the 2 elements have focus.

您可以通过保留一个全局变量和 setTimouts 来等待 200 毫秒的延迟,然后检查两个元素之一是否具有焦点来实现此目的。

var keepFocus = false;

function hideList(){
    if(!keepFocus){
        $('#myList').hide();
    }
}

$('#myInput').blur(function() {
    keepFocus = false;
    window.setTimeout(hideList, 200);
}).focus(function(){
    keepFocus = true;
});


$('#myList').blur(function() {
    keepFocus = false;
    window.setTimeout(hideList, 200);
}).focus(function(){
    keepFocus = true;
});

回答by JK.

You need to be able to say "do this blur() unless the list gains focus at the same time".

您需要能够说“除非列表同时获得焦点,否则执行此模糊()”。

This question says how to detect if an element has focus: Using jQuery to test if an input has focus

这个问题说如何检测一个元素是否有焦点:Using jQuery to test if an input has focus

Then all you need to do is:

那么你需要做的就是:

$("#myInput").blur(function () {
    if (!$("#myList").is(":focus")) {
        $("#myList").hide();
    }
});

回答by Pigalev Pavel

I've faced with the exact same problem, so this is how I solved it.

我遇到了完全相同的问题,所以这就是我解决它的方法。

I came up with the fact that blur()fires earlier than click().

我想出了一个事实,即blur()click().

So I've tried to change click()to mousedown()and found out that mousedown()fires before blur().

所以我尝试更改click()mousedown()并发现mousedown()之前触发了blur().

And to imitate click()you'll have to fire mousedown()and then mouseup()

而要模仿,click()你必须先开火mousedown(),然后mouseup()

So in your case I would do something like this:

所以在你的情况下,我会做这样的事情:

var click_in_process = false; // global

$('#myList').mousedown(function() {
    click_in_process = true;
});

$('#myList').mouseup(function() {
    click_in_process = false;
    $('#myInput').focus();

    // a code of $('#myList') clicking event

});

$('#myInput').blur(function() {
    if(!click_in_process) {
        $('#myList').hide();

        // a code of what you want to happen after you really left  $('#myInput')

    }
});

Demo / example: http://jsfiddle.net/bbrh4/

演示/示例:http: //jsfiddle.net/bbrh4/

Hope it helps!

希望能帮助到你!

回答by Skeets

Pigalev Pavel's answer above works great.

Pigalev Pavel 上面的回答很有效。

However, If you want an even simplier solution, you can just "prevent default" in the "mousedown" of an element to prevent the blur event from taking place. (since preventing default actually means that in the end, the input never looses focus in the first place!)

但是,如果您想要一个更简单的解决方案,您可以在元素的“鼠标按下”中“防止默认”以防止发生模糊事件。(因为防止默认实际上意味着最终,输入永远不会失去焦点!)

Of course, this is only if you're alright with preventing default in the div. It does have some side-effects, like the text is no longer selectable. As long as that's not an issue, this will work.

当然,这只是在您同意防止 div 中的默认值时。它确实有一些副作用,比如文本不再可选。只要这不是问题,这将起作用。

I suppose if you hold the mouse down over the div, move the mouse outside of the div, and then release the mouse, it also doesn't fire the "blur" event. But in my case, I wasn't too worried about that either, since the click started in the target div.

我想如果你在 div 上按住鼠标,将鼠标移到 div 之外,然后释放鼠标,它也不会触发“模糊”事件。但就我而言,我也不太担心,因为点击是在目标 div 中开始的。

$("input").focus(function(){
 $(this).val("");
});

$("input").blur(function(){
 $(this).val("blur event fired!");
});

$("div").mousedown(function(e){
 e.preventDefault();
})
div{
  height: 200px;
  width: 200px;
  background: blue;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input>
<div>
Click here to prevent blur event!
</div>

回答by Adam

The best way to do this is to attach an event handler to the body element, then another handler to the list that stops event propagation:

最好的方法是将一个事件处理程序附加到 body 元素,然后将另一个处理程序附加到停止事件传播的列表中:

$(body).click(function () {
    $("#myList").hide();
});

$("#myList").click(function (e) {
    e.stopImmediatePropagation();
});

This listens for a click outside of #myInput and hides #myList. At the same time, the second function listens for a click on #myList and if it occurs, it prevents the hide() from firing.

这会侦听#myInput 之外的点击并隐藏#myList。同时,第二个函数侦听对#myList 的点击,如果发生,它会阻止 hide() 触发。