我应该如何在导致模糊的点击事件之后触发 Javascript 模糊事件?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4084780/
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-08-23 10:32:26  来源:igfitidea点击:

How should I fire Javascript blur event after click event that causes the blur?

javascriptjqueryeventsonclickonblur

提问by Jake

I have run into this problem a few times and I'm not happy with the solutions I've used before.

我遇到过几次这个问题,我对以前使用的解决方案不满意。

I have an input box with a blur event that validates the content of it and a button which will fill the input box on click. The problem is clicking the button fires the input blur event and then the button click event so content inserted by the button is not what is validated.

我有一个带有模糊事件的输入框,用于验证其内容和一个按钮,该按钮将在单击时填充输入框。问题是单击按钮会触发输入模糊事件,然后是按钮单击事件,因此按钮插入的内容不是经过验证的内容。

See http://jsfiddle.net/jakecr/dL3K3/

http://jsfiddle.net/jakecr/dL3K3/

I know this is the correct behavior but I can't think of a clean way to get around the problem.

我知道这是正确的行为,但我想不出一个干净的方法来解决这个问题。

回答by Yoni Jah

We had a similar problem at work. what we figured out in the end was that the mousedown event will fire before the blur event allowing you to set the content before the validation or even cancel the validation process completely using a flag.

我们在工作中遇到了类似的问题。我们最终发现 mousedown 事件将在 blur 事件之前触发,允许您在验证之前设置内容,甚至使用标志完全取消验证过程。

check this fiddle I made using your example- http://jsfiddle.net/dL3K3/31/

检查我用你的例子制作的这个小提琴 - http://jsfiddle.net/dL3K3/31/

$(function(){
    var flag = true;
    $('input').blur(function(){
        if(!$(this).val() && flag){
            alert("Grrr, It's empty");
        }
    });

    $('button').mousedown(function(){
        flag = false;
    });    
    $('button').mouseup(function(){
        flag = true;
        $('input').val('content').focus();
    });

});

-Edit-

-编辑-

As @mclin Suggested, using the mousedown event and preventDefault will prevent blur behavior. And you can just leave the original click event intact -

正如@mclin 建议的那样,使用 mousedown 事件和 preventDefault 将防止模糊行为。你可以保持原来的点击事件完好无损 -

http://jsfiddle.net/dL3K3/364/

http://jsfiddle.net/dL3K3/364/

$(function(){
    $('input').blur(function(){
        if(!$(this).val()){
            alert("Grrr, It's empty");
        }
    });

    $('button').mousedown(function(e){
        e.preventDefault();
    });    
    $('button').click(function(){
        $('input').val('content');
    });

});

This solution might be a bit cleaner and better for most cases just note that if you use it you'll preventDefault and blur of any other element the focus is currently on but for most use cases that shouldn't be an issue.

对于大多数情况,此解决方案可能更简洁更好,只需注意,如果您使用它,您将防止默认和模糊当前焦点所在的任何其他元素,但对于大多数用例来说,这应该不是问题。

回答by mclin

I have a better solution than Yoni Jah's: call preventDefault on the button's mousedown event. The onBlur never happens so you're free to do whatever in the click event.

我有一个比 Yoni Jah 更好的解决方案:在按钮的 mousedown 事件上调用 preventDefault。onBlur 永远不会发生,所以你可以在点击事件中自由地做任何事情。

This is better because it doesn't change the click behavior by making things happen on mouse down instead of mouse up, which can be unexpected.

这更好,因为它不会通过使事情发生在鼠标按下而不是鼠标抬起来改变点击行为,这可能是意外的。

回答by Vardhini

This might also help:

这也可能有帮助:

Set a timer that delays the blur event action before it fires the button click event.

设置一个计时器,在它触发按钮单击事件之前延迟模糊事件操作。

// Namespace for timer var setTimer = { timer: null }

    $('input,select').blur(function () {
        setTimer.timer = setTimeout(function () {
           functionCall();
        }, 1000);
    });

    $('input,select').focus(function () {
        setTimer.timer = setTimeout(function () {
            functionCall();
        }, 1000);
    });

    $("#btn").click(function () {
        clearTimeout(setTimer.timer);
        functionCall();
    });

回答by pitx3

Separate the input validation logic to it's own function which is called both by the blur event automatically and then by the click event after you've modified the value in the input box. True your validation logic would be called twice, but I'm not seeing a way around that without making a lot more changes.

将输入验证逻辑分离到它自己的函数中,该函数由模糊事件自动调用,然后在修改输入框中的值后由单击事件调用。确实,您的验证逻辑会被调用两次,但如果不进行更多更改,我看不到解决方法。

Example using jQuery:

使用 jQuery 的示例:

$('input').blur(function() {
    validate(this);
});

$('submit').click(function() {
   //modify the input element
   validate(inputElement);
});

var validate = function(obj) {
   // validate the object
}

回答by tic

Sometimes it is useful to get a child object on mouseup, but the parent wants to hide its children on blur. We can cancel the hiding of the children elements, then wait until our mouseup occurs, then force the blur to occur when we are ready

有时在 mouseup 上获取子对象很有用,但父对象希望在模糊时隐藏其子对象。我们可以取消隐藏子元素,然后等到我们的 mouseup 发生,然后在我们准备好时强制发生模糊

js

js

var cancelHide = false;

$('.my-input').blur(function() {
    if (!cancelHide) {
        $('.my-item').hide();
    }
});

$('.my-input').click(function() {
    $('.my-item').show();
});

$('.my-item').mousedown(function() {
    cancelHide = true;
});

$('.my-item').mouseup(function() {
    var text = $(this).text();
    alert(text);
    cancelHide = false;
    $('.my-input').blur();
});

html

html

<input type="text" class="my-input"/>
<div class="my-item">Hello</div>
<div class="my-item">Lovely</div>
<div class="my-item">World</div>

css

css

.my-item {
    display:none;
}

https://jsfiddle.net/tic84/on421rxg/

https://jsfiddle.net/tic84/on421rxg/

Clicking the list items will only alert on mouseup, despite the parent trying to hide them on blur

单击列表项只会在鼠标抬起时发出警报,尽管父级试图在模糊时隐藏它们

回答by Ahti Ahde

The trick is not to use blur and click events, because they are always performed in order of blur first, click second. Instead you should check when the element having focus has changed, because that happens only after the click.

诀窍是不要使用模糊和点击事件,因为它们总是按照先模糊,再点击的顺序执行。相反,您应该检查具有焦点的元素何时发生更改,因为这仅在单击之后发生。

I think I have an elegant solution for this one:

我想我有一个优雅的解决方案:

var alreadyValidated = 'true';

setInterval(function(){
    if(document.activeElement.id != 'validation-field-id'){
        if(alreadyValidated=='false'){
            alreadyValidated = 'true';
            validate(document.activeElement);       
        }
    }
    else {
        alreadyValidated = 'false';
    }
}, 200);

These days all modern browsers support document.activeElement.

现在所有现代浏览器都支持 document.activeElement。