【问题标题】:Firing a handler once for each actual change in an HTML input element为 HTML 输入元素中的每个实际更改触发一次处理程序
【发布时间】:2012-09-28 12:14:59
【问题描述】:

我想为输入字段中的每个实际更改触发一个事件处理程序一次。例如,要验证(每次按键)输入的信用卡号(更改必须在每个更改上进行,因此去抖动/节流不是答案)。

我不能单独使用input,因为 IE9 不会从退格或剪切/删除触发此事件。

我不能单独使用keyup,因为它不能处理来自鼠标的更改(例如粘贴)。

我不能使用change,因为它只会在blur 上触发。

我可以使用$('input').bind('input keyup', handler),但这在大多数情况下会触发两个单独的事件。假设处理程序很昂贵并且运行两次是不可接受的。

我可以包装处理程序,使其仅在当前值与上次检查的值不同时运行,但有更好的方法吗?

【问题讨论】:

    标签: javascript jquery html dom-events


    【解决方案1】:

    检查最后一个输入所做的就是你需要做的。

    这是存储最后一个值的一种方法。

    function handler(){ 
        var tb = jQuery(this);
        var currentValue = tb.val();
        if (tb.data("lastInput") !== currentValue) {
            tb.data("lastInput", currentValue);
            console.log("The current value is " + currentValue);
        } 
    }
    $('input').bind('input keyup', handler);
    

    jsFiddle

    如果你真的不想在你的函数中使用那种逻辑,你总是可以扩展 jQuery。这是一堆更多的代码,但只有一种方法。

    (function(){
        $.fn.oneinput = function(callback) {        
            function testInput(){ 
                var tb = jQuery(this);
                var currentValue = tb.val();
                if (tb.data("lastInput") !== currentValue ) {
                    tb.data("lastInput",currentValue );
                    if(callback) { 
                        callback.call(this) 
                    };
                }
                return this;
            }    
            jQuery(this).bind("keyup input", testInput);
        };
    }(jQuery));
    
    $('input').oneinput( function(){ console.log(this.value); });
    ​
    

    jsfiddle

    【讨论】:

    • @Dr.Molle 所以添加粘贴到事件列表
    【解决方案2】:

    我认为你必须使用setInterval 来监控文本框中的变化

    试试这个demo

    objTextBox = document.getElementById("trackChange");
    oldValue = objTextBox.value;
    
    console.log(oldValue);
    
    function track_change()
       {
         if(objTextBox.value != oldValue)
         {
           oldValue = objTextBox.value;
           console.log("changed")
         }
    
       }
    
    setInterval(function() { track_change()}, 100);
    

    注意:我个人认为这不是最好的解决方案。但我找不到更好的解决方案,至少在任何情况下更换键盘或鼠标时它都可以工作;)

    【讨论】:

    • 此解决方案类似于我当前将处理程序包装在检查更改值中的解决方案,但这具有更高的开销
    • 如果你需要监控100个复选框,你需要100个定时器吗?
    • 不,你可以只创建一个包含 100 个复选框的数组,然后在循环中检查它们以获取单个函数
    【解决方案3】:

    试试这个

        $('input').bind('keyup cut paste', function (event) {
             console.log('value changed');
        });
    

    小提琴http://jsfiddle.net/sXvK2/1/

    【讨论】:

    • 不处理 IE9 中的退格或通过鼠标删除
    • 更新了处理鼠标剪切的答案。退格在 IE9 中对我有用
    • 对不起,这将处理退格。但是,丢失输入处理程序似乎有风险,因为它在边缘情况下失败,例如通过鼠标删除和通过拖动输入/编辑
    【解决方案4】:

    如果您不需要处理程序返回值,您可以将其设为return false,这样它就不会再次启动。

    【讨论】:

    • 不,因为这些是单独的事件return falseevent.stopPropagation() 等将不起作用
    【解决方案5】:

    怎么样

    $el.bind('input', handler);
    $el.bind('keyup', handler);
    ...
    

    【讨论】:

    • 大多数时候触发两个单独的事件
    • 这与我的$('input').bind('input keyup', handler)示例没有什么不同
    猜你喜欢
    • 1970-01-01
    • 2015-05-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多