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


417

我想检测何时文本框的内容已更改。我可以使用keyup方法,但是它也可以检测不会产生字母的击键,例如箭头键。我想到了使用keyup事件执行此操作的两种方法:

  1. 仔细检查所按键的ASCII码是否为字母\退格\删除
  2. 使用闭包来记住按键之前文本框中的文本,并检查是否已更改。

两者看起来都很麻烦。


7
是的,为此捕获密钥是不好的。您可以粘贴所有东西而无需任何按键。
支出者

2
您有机会发布最终解决方案吗?我也需要解决这个问题:)
Matt Dotson 2010年

1
.keyup()事件...更多资讯: stackoverflow.com/questions/3003879/...
维克多小号

1
参见$(“#some-input”)。changePolling() ; 用于检查当前值并触发.change()它是否已更改的包装器。
Joel Purra 2012年

Answers:


714

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

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

...很干净,但可以扩展到:

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

12
“ live”已弃用。所以利用“上” stackoverflow.com/a/15111970/1724777
NavaRajan

21
唯一的缺陷“输入”的是,它不与IE <9.兼容
鲶鱼

5
输入是并非所有浏览器都支持的html5事件。developer.mozilla.org/zh-CN/docs/Web/API/window.oninput
commonpike 2013年

18
您还可以使用以下方法覆盖更多基础:.on('input propertychange paste',function(){
Graeck

23
IE <9的唯一缺点是没有人使用它!
sohaiby 2015年

67

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

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

$('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');
        }
    });
});

3
是的,这类似于我在问题2中的建议。我更喜欢闭包,因为使用全局将使此功能仅适用于一个文本框。无论如何,看来奇怪的jquery并没有更简单的方法来做到这一点。
olamundo

1
这确实很奇怪,但是我怀疑还有更好的方法。您可以使用setInterval,然后检查内容是否每隔0.1秒更改一次,然后执行某些操作。这也将包括鼠标粘贴等。但这听起来并不优雅。
Waleed Amjad

4
仍然有可能无需敲击即可更改内容,例如通过鼠标粘贴。如果您对此有所关注,从理论上讲您也可以捕获鼠标事件,但是该设置更加难看。另一方面,如果您愿意忽略鼠标驱动的更改,则可以这样做。
亚当·贝莱尔

45

'change'事件无法正常运行,但是'input'是完美的。

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

7
尽管我.on建议从1.7开始(而不是.bind)开始使用,但这对我的情况非常有效。
尼克

8
OP未指定需要跨浏览器兼容性。@schwarzkopfb提供了一个解决方案。没有理由拒绝投票,因为您有代表这样做。
David East

3
@David他也没有指定哪个浏览器
ozz 2013年

9
@ jmo21我想我们可以假设当浏览器不是特定的时候进行Web开发时,解决方案应该是跨功能的。该规范支持所有浏览器。
克里斯

3
@Chris“规范支持所有浏览器”-仅当您是施虐者时。没有充分的理由避免对IE 8/9上2%的全球用户使用HTML5。caniuse.com/#feat=input-event
Yarin

39

这个怎么样:

<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


1
我对这个答案的问题是,一旦您模糊了文本框,即使值没有更改,它也会触发。罪魁祸首是“改变”。
贾斯汀

您在使用Chrome吗?看来这是Chrome的错误,而不是jQuery的更改事件bugs.jquery.com/ticket/9335
Catfish

可以,但是如果您console.log输入该字段的值,则有一个小错误,每当您键入一个字符时,它将记录两次。
塞缪尔M.19年

21

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

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

然而!这仍然不能解决所有更改,因为有一种方法可以编辑不涉及任何按键的文本框内容。例如,选择一个文本范围,然后单击鼠标右键。或拖动它。或将文本从另一个应用程序拖放到文本框中。或通过浏览器的拼写检查更改单词。要么...

因此,如果必须检测每个更改,则必须进行轮询。您可以window.setInterval每隔一秒钟(例如)一秒钟检查该字段与之前的值。你也可以电汇onkeyup到同一个功能,使得变化由按键引起的反映更快。

笨拙的?是。就是这样,或者只是以普通的HTML onchange方式进行操作,不要尝试立即更新。


1
input如今,HTML5 事件是可行的,并且可以在所有主要浏览器的当前版本中使用。
Tim Down'4

13
$(document).on('input','#mytxtBox',function () { 
 console.log($('#mytxtBox').val());
});

您可以使用“输入”事件来检测文本框中的内容更改。不要使用'live'绑定事件,因为Jquery-1.7中已弃用该事件,因此请使用'on'。


@NavaRajan刚刚在IE9中再次对其进行了测试。确实在退格上不起作用。
Flores

我不想使用.live,但是我遇到的问题是我已经以某种方式“回到未来”并且在mvc3项目中,团队负责人希望坚持使用“开箱即用”,因此仅EF 4.0,但正在使用jquery 1.5.1 THUS .on()不在1.5.1中,因为它是在jQuery版本1.7 api.jquery.com/on中
Tom Stickel 2013年

5

我假设您希望在文本框更改时进行交互操作(即通过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


4

我建议您看一下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(或者在我的情况下开发自定义窗口小部件),则可以使用窗口小部件或将代码复制到您自己的窗口小部件中。


2

我想问一下您为什么要尝试检测文本框的内容何时实时更改?

一种替代方法是设置一个计时器(通过setIntval?),然后将最后保存的值与当前值进行比较,然后重置一个计时器。这将保证捕获任何更改,无论是由键,鼠标,您未考虑的其他输入设备引起的更改,还是JavaScript从应用程序其他部分更改值(没有人提及的另一种可能性)引起的更改。


我的情况(这使我想到了这个问题)是,当文本框中的数量更改时,我需要显示“更新购物车”按钮。用户不知道他们需要失去焦点,否则可能看不到该按钮。
2009年

抱歉,我不确定这是否回答了“为什么不按计划检查差异”的问题。只需经常检查(每1/4秒),用户就不会知道有什么区别。
DVK,2009年

1

您是否考虑使用更改事件

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

5
AFAIK,仅当元素的焦点丢失时才触发。熟悉闭包的人可能知道这一点。:)
simon

是的,这不会-仅当文本框失去焦点时才调用change事件。我想在按键后立即处理更改。
olamundo

1

textchange通过定制的jQuery垫片使用事件,以实现跨浏览器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 keyupetc 配合使用(!)。只有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测试

这也可以处理粘贴,删除操作,并且不会重复键入键的工作。

如果不使用填充程序,则使用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());    
});  

0

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

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

0

这样的事情应该起作用,主要是因为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);
}

0

此代码检测用户何时更改了文本框的内容并被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);
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.