文本区域变化检测

IT技术 javascript
2021-01-12 14:21:11

如何使用javascript检测textarea上的更改事件?
我正在尝试检测您键入时剩余的可用字符数。

我尝试使用 onchange 事件,但这似乎只在焦点消失时才开始。

6个回答

最好的方法是跨浏览器:使用inputonpropertychangeevents的组合,如下所示:

var area = container.querySelector('textarea');
if (area.addEventListener) {
  area.addEventListener('input', function() {
    // event handling code for sane browsers
  }, false);
} else if (area.attachEvent) {
  area.attachEvent('onpropertychange', function() {
    // IE-specific event handling code
  });
}

input事件处理IE9+、FF、Chrome、Opera 和 Safari,并onpropertychange处理IE8(它也适用于 IE6 和 7,但存在一些错误)。

使用inputand的好处onpropertychange是它们不会不必要地触发(比如按下CtrlShift键时);所以如果你想在 textarea 内容改变时运行一个相对昂贵的操作,这是要走的路

现在 IE 一如既往地在支持这一点上做了一半的工作:从 textarea删除字符时,IE 中input不会也不会onpropertychange触发因此,如果您需要处理 IE 中的字符删除,请使用(而不是使用/ ,因为即使用户按下并按住某个键,它们也只会触发一次)。keypresskeyupkeydown

来源:http : //www.alistapart.com/articles/expanding-text-areas-made-elegant/

编辑:似乎即使上述解决方案也不完美,正如评论中正确指出的那样:addEventListenertextarea 上属性的存在并不意味着您正在使用正常的浏览器;同样,该attachEvent属性的存在并不意味着 IE。如果您希望您的代码真正密封,您应该考虑更改它。请参阅Tim Down 的评论以获取指示。

这是最好的方法。我不喜欢这里的推论(浏览器支持addEventListener并不意味着支持input事件,反之亦然);特征检测会更好。有关问题的讨论,请参阅此博客文章
2021-03-19 14:21:11
不同意,输入不会处理 IE9。不幸的是,通过上下文菜单剪切/粘贴也是输入,退格也是如此。我没有费心去测试,但我不会赌 IE10+ 解决了这个问题。
2021-03-27 14:21:11
@StefanSteiger 这就是为什么我的回答建议keypress在 IE9(也可能是更高版本)中使用该事件来处理这种情况。
2021-03-30 14:21:11
input事件处理程序也可以通过实现.oninput对象属性来定义
2021-04-05 14:21:11
完全同意蒂姆的这一点。oninput是我们应该如何做到这一点,但您可能不应该将其addEventListener用作浏览器支持的测试。无论如何+1。
2021-04-06 14:21:11

为此,您将需要使用onkeyup onchangeonchange 将阻止上下文菜单粘贴,并且 onkeyup 将在每次击键时触发。

有关代码示例,请参阅我关于如何在 textArea施加 maxlength 的答案

我在这里给-1,对不起! onkeyup对于输入检测来说是一个可怕的事件。使用oninputonpropertychange(用于 IE 支持)。
2021-03-26 14:21:11
警告:onkeyup 会给你带来麻烦。示例:假设您应该只在输入内容更改时执行某些操作。如果您假设 keyup 会更改输入,则它不是真的。把重点放在输入上。使用“tab”移动到下一个字段。现在使用“shift+tab”返回输入。keyup 触发,但用户实际上并未更改输入。
2021-03-27 14:21:11
只是想强调 Josh 已经说过的,你应该使用 keyup,而不是 keydown:keydown 似乎在实际对 textarea 进行更改之前被调用,所以你将使用错误的长度(并且你不你真的不知道你有多忙:可能正在输入或删除,并且可能选择文本意味着它不仅仅是 +/- 1)。
2021-04-06 14:21:11
“唯一”的问题是onchange不是在上下文菜单剪切/粘贴时被解雇。
2021-04-08 14:21:11
使用 onkeydown 和 setTimeout 的响应要快得多,这样您就可以获得即时更改检测,而不是等待键被释放。如果您还需要捕获剪切和粘贴,请使用剪切和粘贴事件。
2021-04-08 14:21:11
  • 对于 Google-Chrome,oninput 就足够了(在版本 22.0.1229.94 m 的 Windows 7 上测试)。
  • 对于 IE 9,oninput 将通过上下文菜单和退格键捕获除剪切之外的所有内容。
  • 对于 IE 8,除了 oninput 之外,还需要 onpropertychange 来捕获粘贴。
  • 对于 IE 9 + 8,需要使用 onkeyup 来捕捉退格。
  • 对于 IE 9 + 8,onmousemove 是我发现通过上下文菜单捕捉剪切的唯一方法

未在 Firefox 上测试。

    var isIE = /*@cc_on!@*/false; // Note: This line breaks closure compiler...

    function SuperDuperFunction() {
        // DoSomething
    }


    function SuperDuperFunctionBecauseMicrosoftMakesIEsuckIntentionally() {
        if(isIE) // For Chrome, oninput works as expected
            SuperDuperFunction();
    }

<textarea id="taSource"
          class="taSplitted"
          rows="4"
          cols="50"
          oninput="SuperDuperFunction();"
          onpropertychange="SuperDuperFunctionBecauseMicrosoftMakesIEsuckIntentionally();"
          onmousemove="SuperDuperFunctionBecauseMicrosoftMakesIEsuckIntentionally();"
          onkeyup="SuperDuperFunctionBecauseMicrosoftMakesIEsuckIntentionally();">
Test
</textarea>
很棒的函数名称:)
2021-03-26 14:21:11

我知道这不完全是您的问题,但我认为这可能有用。对于某些应用程序,不是每次按下键时都触发更改功能是很好的。这可以通过这样的事情来实现:

var text = document.createElement('textarea');
text.rows = 10;
text.cols = 40;
document.body.appendChild(text);

text.onkeyup = function(){
var callcount = 0;
    var action = function(){
        alert('changed');
    }
    var delayAction = function(action, time){
        var expectcallcount = callcount;
        var delay = function(){
            if(callcount == expectcallcount){
                action();
            }
        }
        setTimeout(delay, time);
    }
    return function(eventtrigger){
        ++callcount;
        delayAction(action, 1200);
    }
}();

这通过测试是否在某个延迟期内触发了较新的事件来起作用。祝你好运!

+1 表示“节流”延迟动作!我在我的应用程序中使用了类似的东西。
2021-03-20 14:21:11

我知道这个问题是特定于 JavaScript 的,但是,似乎没有好的、干净的方法来始终检测当前所有浏览器中的 textarea 何时更改。我了解到 jquery 已经为我们处理好了。它甚至可以处理对文本区域的上下文菜单更改。无论输入类型如何,都使用相同的语法。

    $('div.lawyerList').on('change','textarea',function(){
      // Change occurred so count chars...
    });

或者

    $('textarea').on('change',function(){
      // Change occurred so count chars...
    });
我发现更改事件与 jQuery 的一致性并不比普通 JS 更一致。我使用了 jQuery bind("input cut paste"...,它的作用就像一个魅力——使用键盘或上下文菜单打字、剪切和粘贴;甚至拖放文本。
2021-03-23 14:21:11
不幸的是,FF 不会changetextarea.
2021-03-29 14:21:11