如何在jQuery中绑定textarea的变化事件?

251

我想捕获<textarea>的任何更改。例如,键入任何字符(删除,回退)或鼠标点击和剪切/粘贴等操作。是否有一个jQuery事件可以触发所有这些事件?

我尝试了change事件,但它仅在从组件中切换时才触发回调。

用途:如果<textarea>包含任何文本,我想启用一个按钮。


18
仅将按键事件绑定不足以确保文本内容的准确性,因为鼠标操作(如从上下文菜单中的“粘贴”/“剪切”或拖放)也可以更改文本内容。 - Konstantin Smolyanin
1
类似的问题在Textarea onchange detection中有讨论。 - dma_k
11个回答

366

实际上,试试这个:

$('#textareaID').bind('input propertychange', function() {

      $("#yourBtnID").hide();

      if(this.value.length){
        $("#yourBtnID").show();
      }
});

演示

对于您所做的任何更改,如打字、剪切、粘贴等,都有效。


5
@Senthilnathan说:“对我来说,在Chrome和Firefox中都不起作用,因为它不仅仅是propertychange,还有input。” - Blaster
5
请注意,我刚刚发现在IE9中(没有检查IE的旧版本),当在文本区域按下退格键时,这两个事件都不会触发。 - Zappa
34
这些演示使用的是<input type="text">,而不是<textarea> - Ben Collins
5
将“input propertychange” 更改为“input change”,以便在IE9中也能正常工作。http://paulbakaus.com/2012/06/14/propertychange-on-internet-explorer-9/ - c0D3l0g1c
13
我看到你在 DEMO 中使用了 <input type="textarea" cols="10" rows="4" />,真的吗? - DrLightman
显示剩余5条评论

160

bind已经过时,请使用on代替:

$("#textarea").on('change keyup paste', function() {
    // your code here
});
注意:上面的代码会多次触发,每个匹配的触发类型都会触发一次。为了处理这种情况,请执行以下操作:
var oldVal = "";
$("#textarea").on("change keyup paste", function() {
    var currentVal = $(this).val();
    if(currentVal == oldVal) {
        return; //check to prevent multiple simultaneous triggers
    }

    oldVal = currentVal;
    //action to be performed on textarea changed
    alert("changed!");
});

jsFiddle演示


3
on("change", function() ....) 这一部分对我来说没有用。没有触发任何警报、控制台日志或其他任何东西。不过,keyup 的效果非常好。 - Sebastialonso
3
on("change", function() ... 只有在文本区域失去焦点时才会触发。请参考我之前的问题(https://dev59.com/32Qm5IYBdhLWcg3w0Bq5),并在这个 JSFiddle 上尝试一下(http://jsfiddle.net/6bt2g/55/) - 改变文本区域的内容,然后点击文本区域外部,你应该能看到变化事件被触发。 - SNag
@SNag,这段代码在Chrome 45上无法运行,但在FF 41上可以正常工作。 - DariusVE
如果你被困在使用1.7版本之前的jQuery中,那么这就不适用。 - Code Jockey
1
你可以使用.one("change keyup paste", function ...代替.onone事件监听器只会触发一次。 - solitud
显示剩余9条评论

94

使用input事件。

var button = $("#buttonId");
$("#textareaID").on('input',function(e){
  if(e.target.value === ''){
    // Textarea has no value
    button.hide();
  } else {
    // Textarea has a value
    button.show();
  }
});

对于Internet Explorer浏览器,需要9+版本或者10+版本才能正常运行。 - Udi
2
这个解决方案非常好用。 完美地克服了change()和keypress()事件处理程序的限制。非常感谢。 - Vickar
这似乎对粘贴事件无效?感谢您的帮助。 - Crashalot
@Crashalot 实际上,这个功能在键盘和鼠标的输入、粘贴、删除方面都能正常工作。我刚测试了最新版本的 Chrome、Firefox 和 Edge(在撰写此评论时)。 - informatik01

27

这个问题需要一个更为更新的回答,并且需要给出来源。以下是实际上有效的方法(当然你不必相信我的话):

// Storing this jQuery object outside of the event callback 
// prevents jQuery from having to search the DOM for it again
// every time an event is fired.
var $myButton = $("#buttonID")

// input           :: for all modern browsers [1]
// selectionchange :: for IE9 [2]
// propertychange  :: for <IE9 [3]
$('#textareaID').on('input selectionchange propertychange', function() {

  // This is the correct way to enable/disabled a button in jQuery [4]
  $myButton.prop('disabled', this.value.length === 0)

}

1: https://developer.mozilla.org/zh-CN/docs/Web/Events/input#浏览器兼容性
2: oninput 在 IE9 中当我们按 BACKSPACE / DEL / 剪切时不会执行
3: https://msdn.microsoft.com/zh-cn/library/ms536956(v=vs.85).aspx
4: http://api.jquery.com/prop/#prop-propertyName-function

但是,为了实现一个更全局的解决方案,您可以在整个项目中使用textchange jQuery 插件来获得一个新的、跨浏览器兼容的textchange事件。它由同一个人开发,该人为 Facebook 的 ReactJS 实现了相应的 onChange 事件,并且他们在几乎整个网站中使用它。我认为可以放心地说,如果它足够强大,足以满足 Facebook 的要求,那么它对您来说也足够强大。 :-)

更新:如果您需要在 Internet Explorer 中支持拖放等功能,则可能需要查看pandell 更近期的更新版本的 jquery-splendid-textchange


虽然似乎只有将“selectionchange”应用于文档时才起作用。但是可以使用“document.activeElement”获取活动元素。 - tfE

14

2018年,没有JQUERY

问题是使用jQuery,仅供参考。

JS

let textareaID = document.getElementById('textareaID');
let yourBtnID = document.getElementById('yourBtnID');
textareaID.addEventListener('input', function() {
    yourBtnID.style.display = 'none';
    if (textareaID.value.length) {
        yourBtnID.style.display = 'inline-block';
    }
});

HTML

<textarea id="textareaID"></textarea>
<button id="yourBtnID" style="display: none;">click me</div>

这似乎对粘贴事件无效?感谢您的帮助。 - Crashalot

5

这里有一个比之前提到的版本稍微不同的(现代)版本。在IE9中进行了测试:

$('#textareaID').on('input change keyup', function () {
  if (this.value.length) {
    // textarea has content
  } else {
    // textarea is empty
  }
});

对于过时的浏览器,您可能还需要添加selectionchangepropertychange(如其他答案中所述)。但是在IE9中,selectionchange对我无效。这就是为什么我添加了keyup


2
尝试使用focusout完成此操作。
$("textarea").focusout(function() {
   alert('textarea focusout');
});

2

试试这个...

$("#txtAreaID").bind("keyup", function(event, ui) {                          

              // Write your code here       
 });

8
仅绑定按键事件是不够的,因为文本可以通过鼠标进行更改(从上下文菜单中的“粘贴”/“剪切”或拖放操作)。 - Konstantin Smolyanin

1

.delegate 是唯一在使用 jQuery JavaScript库 v2.1.1 时可用的方法。

 $(document).delegate('#textareaID','change', function() {
          console.log("change!");
    });

0

经过一些实验,我想出了这个实现方法:

$('.detect-change')
    .on('change cut paste', function(e) {
        console.log("Change detected.");
        contentModified = true;
    })
    .keypress(function(e) {
        if (e.which !== 0 && e.altKey == false && e.ctrlKey == false && e.metaKey == false) {
            console.log("Change detected.");
            contentModified = true;
        }
    });

处理输入和选择的任何更改,以及忽略箭头键和像Ctrl、Cmd、功能键等的其他键。

注意:我只在FireFox中尝试过这个功能,因为它是为FireFox插件设计的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接