如何检测文本框的内容已经改变

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

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

两者看起来都有点麻烦。

559360 次浏览

在HTML/标准JavaScript中使用onchange事件。

在jQuery中,这是变化()事件。例如:

$('element').change(function() { // do something } );

编辑

看了一些评论后,你觉得:

$(function() {
var content = $('#myContent').val();


$('#myContent').keyup(function() {
if ($('#myContent').val() != content) {
content = $('#myContent').val();
alert('Content has been changed');
}
});
});

你是否考虑使用更改事件 ?

$("#myTextBox").change(function() { alert("content changed"); });

使用闭包来记住按键之前复选框中的文本是什么,并检查它是否已更改。

是的。不一定要使用闭包,但需要记住旧值并将其与新值进行比较。

然而!这仍然不会捕捉每一个变化,因为有一种编辑文本框内容的方法,不涉及任何按键。例如,选择一个文本范围,然后右键单击剪切。或者拖着它。或者从另一个应用程序中删除文本到文本框中。或者通过浏览器的拼写检查更改一个单词。还是……

因此,如果必须检测每个变化,就必须进行轮询。你可以window.setInterval来检查字段与它之前的值每(比如说)秒。你也可以将onkeyup连接到相同的函数,这样由按键引起的的变化就能更快地反映出来。

麻烦吗?是的。但这就是正常的HTML onchange方式,不要尝试即时更新。

我想问为什么你试图检测当文本框的内容改变实时地?

另一种方法是设置一个计时器(通过setIntval?),并将上次保存的值与当前值进行比较,然后重置计时器。这将保证捕捉任何变化,无论是由键、鼠标、其他你没有考虑到的输入设备引起的,甚至是JavaScript从应用程序的不同部分改变值(另一种没有人提到的可能性)。

我假设当文本框发生变化时,您希望做一些交互式的事情(即通过ajax检索一些数据)。我在寻找同样的功能。我知道使用全局变量不是最健壮或最优雅的解决方案,但我就是这么做的。这里有一个例子:

var searchValue = $('#Search').val();
$(function () {
setTimeout(checkSearchChanged, 0.1);
});


function checkSearchChanged() {
var currentValue = $('#Search').val();
if ((currentValue) && currentValue != searchValue && currentValue != '') {
searchValue = $('#Search').val();
$('#submit').click();
}
else {
setTimeout(checkSearchChanged, 0.1);
}
}

这里需要注意的一件关键事情是,我使用的是setTimeout而不是setInterval,因为我不想同时发送多个请求。这确保计时器在提交表单时“停止”,在请求完成时“启动”。当我的ajax调用完成时,我通过调用checkSearchChanged来做到这一点。显然,你可以展开它来检查最小长度,等等。

在我的例子中,我使用的是ASP。Net MVC,所以你可以看到如何将其与MVC Ajax结合在一起,以及在下面的帖子中:

http://geekswithblogs.net/DougLampe/archive/2010/12/21/simple-interactive-search-with-jquery-and-asp.net-mvc.aspx

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

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

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

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

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

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

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

基本上它们都做了,它们绑定到input, keydown, keyup, keypress, focus and blur。然后它们对诸如page up, page down, up arrow key and down arrow key之类的各种键有特殊处理。在获取文本框的内容之前使用计时器。当用户输入一个与命令不对应的键(上键、下键等)时,会有一个计时器在大约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(或者像我这样开发自定义小部件),可以使用小部件,也可以将代码复制到自己的小部件中。

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

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

您可以使用'input'事件来检测文本框中的内容更改。不要使用'live'来绑定事件,因为它在Jquery-1.7中已弃用,所以要使用'on'。

这个怎么样:

& lt;jQuery 1.7

$("#input").bind("propertychange change keyup paste input", function(){
// do stuff;
});

jQuery 1.7

$("#input").on("propertychange change keyup paste input", function(){
// do stuff;
});

这适用于IE8/IE9, FF, Chrome

这里有一个完整的工作示例在这里

<html>
<title>jQuery Summing</title>
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"> </script>
$(document).ready(function() {
$('.calc').on('input', function() {
var t1 = document.getElementById('txt1');
var t2 = document.getElementById('txt2');
var tot=0;
if (parseInt(t1.value))
tot += parseInt(t1.value);
if (parseInt(t2.value))
tot += parseInt(t2.value);
document.getElementById('txt3').value = tot;
});
});
</script>
</head>
<body>
<input type='text' class='calc' id='txt1'>
<input type='text' class='calc' id='txt2'>
<input type='text' id='txt3' readonly>
</body>
</html>

通过自定义的jQuery shim使用textchange事件来实现跨浏览器的input兼容性。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>content</textarea>,它并不总是适用于change keyup等(!)只有jQuery on("input propertychange")一致地处理<textarea>标记,以上是对所有不理解input事件的浏览器的一个补充。

<!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 test

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

如果不使用垫片,使用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());
});

类似这样的东西应该可以工作,主要是因为focusfocusout最终会有两个单独的值。我在这里使用data,因为它在元素中存储值,但不触及DOM。它也是存储与其元素相连接的值的一种简单方法。您也可以轻松地使用范围更高的变量。

var changed = false;


$('textbox').on('focus', function(e) {
$(this).data('current-val', $(this).text();
});


$('textbox').on('focusout', function(e) {
if ($(this).data('current-val') != $(this).text())
changed = true;
}
console.log('Changed Result', changed);
}

该代码检测文本框的内容何时被用户更改,何时被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);
document.getElementById('txtrate' + rowCount).onchange = function () {
// your logic
};

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

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

在我的场景中完美工作。它只在值改变时起作用。 可以使用document代替$ sign。getElementById太< / p >