我想检测文本框的内容何时发生了变化。我可以使用keyup方法,但这也将检测不生成字母的击键,如方向键。我想到了两种使用keyup事件的方法:

显式检查所按键的ascii码是否为字母\backspace\delete 使用闭包来记住在击键之前文本框中的文本是什么,并检查这是否已更改。

两者看起来都有点麻烦。


当前回答

我建议看看jQuery UI自动完成小部件。他们在那里处理了大多数情况,因为他们的代码基础比大多数人更成熟。

下面是一个演示页面的链接,您可以验证它的工作。http://jqueryui.com/demos/autocomplete/#default

阅读源代码,看看他们是如何解决问题的,你会得到最大的好处。你可以在这里找到它:https://github.com/jquery/jquery-ui/blob/master/ui/jquery.ui.autocomplete.js。

基本上它们都做了,它们绑定到输入,键下,键上,键按,聚焦和模糊。然后它们对各种键都有特殊的处理,比如向上翻页,向下翻页,向上箭头键和向下箭头键。在获取文本框的内容之前使用计时器。当用户输入一个与命令不对应的键(上键、下键等)时,会有一个计时器在大约300毫秒后浏览内容。它在代码中是这样的:

// switch statement in the 
switch( event.keyCode ) {
            //...
            case keyCode.ENTER:
            case keyCode.NUMPAD_ENTER:
                // when menu is open and has focus
                if ( this.menu.active ) {
                    // #6055 - Opera still allows the keypress to occur
                    // which causes forms to submit
                    suppressKeyPress = true;
                    event.preventDefault();
                    this.menu.select( event );
                }
                break;
            default:
                suppressKeyPressRepeat = true;
                // search timeout should be triggered before the input value is changed
                this._searchTimeout( event );
                break;
            }
// ...
// ...
_searchTimeout: function( event ) {
    clearTimeout( this.searching );
    this.searching = this._delay(function() { // * essentially a warpper for a setTimeout call *
        // only search if the value has changed
        if ( this.term !== this._value() ) { // * _value is a wrapper to get the value *
            this.selectedItem = null;
            this.search( null, event );
        }
    }, this.options.delay );
},

使用计时器的原因是为了让UI有机会更新。当Javascript运行时,UI不能被更新,因此需要调用delay函数。这适用于其他情况,如保持对文本框(由该代码使用)的关注。

因此,如果不使用jQuery UI(或者像我这样开发自定义小部件),可以使用小部件,也可以将代码复制到自己的小部件中。

其他回答

开始观察“输入”事件而不是“改变”事件。

jQuery('#some_text_box').on('input', function() {
    // do your stuff
});

...这是漂亮和干净的,但可以进一步扩展到:

jQuery('#some_text_box').on('input propertychange paste', function() {
    // do your stuff
});

“change”事件不能正常工作,但“input”是完美的。

$('#your_textbox').bind('input', function() {
    /* This will be fired every time, when textbox's value changes. */
} );

该代码检测文本框的内容何时被用户更改,何时被Javascript代码修改。

var $myText = jQuery("#textbox");

$myText.data("value", $myText.val());

setInterval(function() {
    var data = $myText.data("value"),
    val = $myText.val();

    if (data !== val) {
        console.log("changed");
        $myText.data("value", val);
    }
}, 100);

使用textchange事件通过定制的jQuery shim跨浏览器输入兼容性。http://benalpert.com/2013/06/18/a-near-perfect-oninput-shim-for-ie-8-and-9.html(最近分叉github: https://github.com/pandell/jquery-splendid-textchange/blob/master/jquery.splendid.textchange.js)

这处理所有输入标签,包括<textarea>内容</textarea>,这并不总是与改变keyup等工作(!)只有jQuery on("input propertychange")处理<textarea>标签一致,以上是对所有不理解输入事件的浏览器的一个填充。

<!DOCTYPE html>
<html>
<head>
<script class="jsbin" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script src="https://raw.githubusercontent.com/pandell/jquery-splendid-textchange/master/jquery.splendid.textchange.js"></script>
<meta charset=utf-8 />
<title>splendid textchange test</title>

<script> // this is all you have to do. using splendid.textchange.js

$('textarea').on("textchange",function(){ 
  yourFunctionHere($(this).val());    });  

</script>
</head>
<body>
  <textarea style="height:3em;width:90%"></textarea>
</body>
</html>

JS Bin测试

这还可以处理粘贴、删除,并且不会重复keyup上的工作。

如果不使用shim,请使用jQuery on("input propertychange")事件。

// works with most recent browsers (use this if not using src="...splendid.textchange.js")

$('textarea').on("input propertychange",function(){ 
  yourFunctionHere($(this).val());    
});  
document.getElementById('txtrate' + rowCount).onchange = function () {            
       // your logic
};

这个工作得很好,但在点击时也会触发事件,这并不好。我的系统进入循环。 而

$('#txtrate'+rowCount).bind('input', function() {
        //your logic
} );

在我的场景中非常适用。它只在值改变时起作用。 可以使用document代替$ sign。getElementById太