32

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

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

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

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

4

6 回答 6

40

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

检查我用你的例子制作的这个小提琴 - 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();
    });

});

-编辑-

正如@mclin 建议的那样,使用 mousedown 事件和 preventDefault 将防止模糊行为。而且您可以保持原始点击事件不变 -

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

});

对于大多数情况,此解决方案可能更简洁更好,请注意,如果您使用它,您将防止默认并模糊当前关注的任何其他元素,但对于大多数用例而言,这不应该成为问题。

于 2012-03-26T09:40:36.313 回答
23

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

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

于 2013-01-31T19:24:51.857 回答
8

这也可能有帮助:

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

// 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();
    });
于 2010-12-30T05:03:38.650 回答
2

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

使用 jQuery 的示例:

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

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

var validate = function(obj) {
   // validate the object
}
于 2010-11-03T18:41:31.487 回答
0

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

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

<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

.my-item {
    display:none;
}

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

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

于 2015-10-27T22:53:32.517 回答
-1

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

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

var alreadyValidated = 'true';

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

如今,所有现代浏览器都支持 document.activeElement。

于 2012-02-23T17:02:11.863 回答