jQueryUI日期选择器在传递日期之前触发输入框的模糊事件,该如何避免或解决?

24

我有一个文本输入框,绑定了模糊事件的一些验证。在这个字段上有一个日期选择器(来自jqueryUI的版本),因此当您点击该字段时,日期选择器会显示出来,然后您点击一个日期,它将日期填充到字段中,就像日期选择器所做的那样。但是,在输入日期之前,似乎输入字段会由于某种原因而触发其模糊事件。看起来焦点在日期填充到字段之前已经离开了输入框。因此,我的验证会在用户选择日期时立即触发,而不是在日期实际填入字段后运行,这是不应该的。是否有人知道为什么在那个时间点发生了模糊,并且如何解决?

7个回答

19
当用户点击输入框之外的区域(以选择日期)时,输入框将失去焦点。这是无法避免的。因此,与其在失去焦点时触发验证,不如使用日期选择器的onSelect回调函数。
$('.selector').datepicker({
    onSelect: function(dateText) { /* validation here */ }
});

如果您想保留您的onblur事件,您可以推迟验证以允许日期选择器在验证触发之前填写字段,方法如下:

$('#myform input').blur(function () {
    setTimeout(function () { /* validation here */ }, 1);
});

使用setTimeout来处理并发问题可能看起来像一个技巧,但由于JavaScript是单线程的本质,这个方法运行得相当不错。jQuery的创始人John Resig在这篇博客文章中谈论了它。


嗯,这可能可行。我得想办法绕过为日期选择器字段注册验证到模糊的方式,因为我的验证模糊事件处理程序在onload中注册到所有文本字段,但是可行的。 - Purrell
我添加了一种不同的方法,可能更适合您的需求。 - Magnar

8
您可以尝试这个方法:
$(".date-pick").datepicker({
...
onSelect: function() {
this.focus();
},
onClose: function() {
this.blur();
}
...

6
我发现只有使用以下代码,才能始终让键盘和选择器选择事件同时工作:
 $(".date-picker")
            .datepicker("option", "onSelect", function (dateText, inst) {
                // User Method
            })
            .change(function () {
                // User Method
            });

仅使用模糊事件的问题在于,当选择日期时,日期选择器会在将值传递给输入框之前触发输入框的模糊事件。


5
Magnars的回答非常好。为了让新手更加易懂,这里再提供一种适用于在模糊状态下进行验证框架的方法。我会解除绑定在文档就绪/页面加载时设置的验证模糊事件(这是验证的常见模式),然后将其放回到onclose日期选择器选项中。显然,datepicker关闭事件发生在datepicker将信息传递到字段之后,因此,在那一点上运行模糊验证是可以的。这样,我就不必在验证代码本身中为字段做任何特殊处理。如果其他人遇到此问题,则两种方法都可能适用。
$('#datefield').datepicker(
{beforeShow: function(input) {
                             $(input).unbind('blur');
             },
 onClose: function(dateText, inst) {
                             $(this).validationEngine();this.focus();this.blur() }
});

在我的框架中,'.validationEngine()' 是注册验证处理程序的方法。


3

提醒一下这个帖子,因为我对已接受的解决方案有些困难。

我发现当日历控件的'onClose'事件触发时,最容易触发'change'事件。这样可以确保输入元素的'change'事件总是被触发:

$('#my_element').datepicker({
    onClose: function() {
        $(this).trigger('change');
    }
});

这可能看起来很傻,因为它有时会在没有任何更改的情况下触发。然而,它比日期选择器的“onSelect”更可靠,并帮助我避免了焦点离开或模糊事件在日期选择器事件之前触发的问题。


1

在jQuery中创建自定义事件并将其绑定到文本框。然后,在datepicker的onClose事件上触发该事件。这样,如果您移出文本框,则会触发自定义事件。

$("inputText").bind('CustomEventName',function(){//your validate method code});

在日期选择器中

$("#inputText").datePicker({onClose:function(){ $(this).trigger('CustomEventName')});

1

我和你一样遇到了同样的问题,Magnar的回答有所帮助,但并未完全解决问题。

你已经找到了潜在的原因。用户与日历交互的操作会使输入框失去焦点。在这种情况下(对于jQuery非侵入式验证),将会触发onBlur事件,从而验证该输入框。此时该值仍然是先前的值,直到用户选择某个值。

因此,在Magnar的答案基础上,他建议您需要在日历onChange事件中重新验证输入字段。最明显的方法是调用$("form").valid(),但是这会验证整个表单。

更好的方法是只验证与日期选择器连接的输入字段,您可以通过以下方式触发:

$('#myform input').blur(function () {
    var that = this;
    setTimeout(function () {
        $(that).trigger("focus").trigger("blur");
    }, 100);
});

现在只有您的输入字段经过验证,因为您已经模拟了用户点击输入字段的操作。

1
当我这样做时,模糊事件会不断触发-我猜是递归循环。此外,由于不断触发焦点事件,日期选择器会立即重新出现,因此用户无法隐藏选择器。 - Tofuwarrior

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接