如何在单击事件后触发Javascript模糊事件,从而导致模糊?

时间:2022-12-03 20:12:14

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.

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

6 个解决方案

#1


33  

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事件会在模糊事件发生之前触发,允许您在验证之前设置内容,甚至使用标记完全取消验证过程。

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.

对于大多数情况,这个解决方案可能更简洁、更好,只要注意,如果您使用它,您将避免当前关注的任何其他元素的默认和模糊,但是对于大多数不应该成为问题的用例来说。

#2


19  

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.

这样做更好,因为它不会通过让鼠标向下而不是鼠标向上来改变点击行为,这可能是意料之外的。

#3


8  

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

#4


1  

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.

将输入验证逻辑与它自己的函数分离,该函数由blur事件自动调用,然后在修改输入框中的值后由click事件调用。确实,您的验证逻辑将被调用两次,但是我认为如果不做更多的更改,就无法解决这个问题。

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
}

#5


0  

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上获取子对象是有用的,但是父对象希望在blur中隐藏子对象。我们可以取消子元素的隐藏,然后等待鼠标事件发生,然后在准备就绪时强制执行模糊

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

单击列表项将只在mouseup上发出警报,尽管父元素试图在blur中隐藏它们

#6


-2  

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.

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

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。

#1


33  

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事件会在模糊事件发生之前触发,允许您在验证之前设置内容,甚至使用标记完全取消验证过程。

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.

对于大多数情况,这个解决方案可能更简洁、更好,只要注意,如果您使用它,您将避免当前关注的任何其他元素的默认和模糊,但是对于大多数不应该成为问题的用例来说。

#2


19  

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.

这样做更好,因为它不会通过让鼠标向下而不是鼠标向上来改变点击行为,这可能是意料之外的。

#3


8  

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

#4


1  

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.

将输入验证逻辑与它自己的函数分离,该函数由blur事件自动调用,然后在修改输入框中的值后由click事件调用。确实,您的验证逻辑将被调用两次,但是我认为如果不做更多的更改,就无法解决这个问题。

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
}

#5


0  

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上获取子对象是有用的,但是父对象希望在blur中隐藏子对象。我们可以取消子元素的隐藏,然后等待鼠标事件发生,然后在准备就绪时强制执行模糊

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

单击列表项将只在mouseup上发出警报,尽管父元素试图在blur中隐藏它们

#6


-2  

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.

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

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。