按下键时,jQuery代码触发两次bind('keyup change')

时间:2012-06-30 18:06:27

标签: jquery events

我有一个数字输入,应该在每次更改时触发jQuery。 为此,我执行$('#id').bind('keyup change', ...);,这是在任何键盘或鼠标控制器更改时触发的。

这适用于鼠标点击(触发器change)和键入数字(触发器keyup)。但是对于光标键,它会触发changekeyup。我怎样才能使它在所有情况下只触发一次?

以下是显示问题的示例:http://jsfiddle.net/jSjkE/

3 个答案:

答案 0 :(得分:13)

您对onchange事件有错误的概念。

当元素的值发生变化时会触发 NOT ,而只会在满足2个条件时触发:

  • 元素模糊(失去焦点);
  • 该元素的值与获得焦点时的值不同。

注意:以上是针对text类型的输入。对于类型checkbox / radio类型,只要其checked属性发生更改,就会触发;对于select元素,只要其所选选项发生更改,就会触发。

当您按Chrome的onchange向上/向下箭头时,input type="number"事件(可能错误地)会触发。您应该依赖它,因为许多其他主流浏览器甚至没有实现数字输入,并且可能不会遵循此行为。

相反,当您使用HTML5时,您应该依赖于oninput HTML5事件,该事件会在元素值更新时触发。

$(function() {
    var count = 0;
    $('#num').on('input', function(e) {
        console.log('update ' + (++count) + ' Value: ' + this.value);    
    });
});​

<强> Fiddle

修改

对于较旧(和非HTML5)的浏览器,您可以使用keyup事件作为后备:

$('#num').on('input keyup', function(e) {

为非HTML5浏览器执行此操作的最有弹性的方法是让setInterval不断检查元素的值是否已更改,因为如果您选择某些文本并拖动它,keyup不会触发进入文本框 - 您可以尝试.on('input keyup mouseup',但如果用户使用浏览器的编辑&gt;则不会触发粘贴菜单。

<强> EDIT2:

如果您不想使用setInterval,可以在.on / .bind中放置一个巨大的事件地图,并通过存储当前值来检查值是否已更改元素的.data()

var count = 0;
$('#num').on('input keyup change', function(e) {
    if (this.value == $(this).data('curr_val'))
        return false;
    $(this).data('curr_val', this.value);

    console.log('update ' + (++count) + ' Value: ' + this.value);
});

Fiddle

我已将onchange事件添加到事件地图中,因此即使oninputonkeyup失败(使用浏览器菜单粘贴数据的非html5浏览器),当元素失去焦点时,onchange事件仍将触发。

以下是使用注释setInterval.data()进行的最终编辑,以避免使用全局变量,因此您可以选择使用哪种回退:

$(function() {
    var $num = $('#num');
    $num.data('curr_val', $num.val()); //sets initial value

    var count = 0;
    setInterval(function(){
        if ($num.data('curr_val') == $num.val()) //if it still has same value
            return false; //returns false
        $num.data('curr_val', $num.val()); //if val is !=, updates it and
        //do your stuff
        console.log('update ' + (++count) + ' Value: ' + $num.val());
    }, 100); //100 = interval in miliseconds
});

<强> Fiddle

答案 1 :(得分:0)

$('input').unbind('keyup').bind('keyup',function(e){ ...

答案 2 :(得分:0)

Keyup 始终适用于输入、搜索字段,您可以防止更改事件如下:并保持更改事件适用于其他控件,即选择。

// Prevent trigger change as keyup event already triggered so no twice call
if ((e.target.type == 'input' || e.target.type == 'search') && e.type == 'change') {
    return;
}