关于javascript:Textarea onchange检测

Textarea onchange detection

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

我尝试使用onchange事件,但这似乎仅在焦点移开时才起作用。


现在是2012年,后PC时代已经到来,我们仍然必须为像这样的基本问题而奋斗。这应该非常简单。

在实现梦想之前,最好的方法是跨浏览器:使用inputonpropertychange事件的组合,如下所示:

1
2
3
4
5
6
7
8
9
10
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,但存在一些错误)。

使用inputonpropertychange的优点是它们不会不必要地触发(例如按CtrlShift键时);因此,如果您希望在文本区域内容更改时执行相对昂贵的操作,则可以采用此方法。

现在,IE一如既往地在支持该任务上做得很努力:当从文本区域删除字符时,inputonpropertychange在IE中均不会触发。因此,如果需要处理IE中字符的删除,请使用keypress(与使用keyup / keydown相对,因为即使用户按下并按住一个键,它们也仅触发一次)。

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

编辑:似乎上述解决方案也不是完美的,正如注释中正确指出的那样:textarea上addEventListener属性的存在并不意味着您正在使用正常的浏览器;类似地,attachEvent属性的存在并不表示IE。如果您希望代码确实是气密的,则应考虑更改它。有关指针,请参见Tim Down的评论。


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

请参阅我的有关如何对textArea施加maxlength的答案以获取代码示例。


  • 对于Google-Chrome,oninput就足够了(在Windows 7上,版本22.0.1229.94 m进行了测试)。
  • 对于IE 9,oninput将捕获除通过contextmenu和Backspace剪切以外的所有内容。
  • 对于IE 8,除了oninput外,还需要onpropertychange来捕获粘贴。
  • 对于IE 9 + 8,需要onkeyup来捕获退格键。
  • 对于IE 9 + 8,onmousemove是我发现通过contextmenu进行剪切的唯一方法

未在Firefox上测试。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
    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>


我知道这不完全是您的问题,但我认为这可能有用。
对于某些应用程序,最好不要每次按一次键都启用更改功能。这可以通过以下方式实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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);
    }
}();

这通过测试是否在某个延迟时间内触发了最近的事件而起作用。祝好运!


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

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

要么

1
2
3
    $('textarea').on('change',function(){
      // Change occurred so count chars...
    });


您可以在textarea更改时收听事件,并根据需要进行更改。这是一个例子。

1
2
3
4
5
6
7
8
9
10
(() => {
\tconst textArea = document.getElementById('my_text_area');
  textArea.addEventListener('input', () => {
    let textLn =  textArea.value.length;
    if(textLn >= 100) {
      textArea.style.fontSize = '10pt';
    }

  })
})()
1
2
3
4
5
<html>
<textarea id='my_text_area' rows="4" cols="50" style="font-size:40pt">
This text will change font after 100.
</textarea>
</html>


如果将Keyup与HTML5输入验证/样式属性配对,就足够了。因此,创建一个模式(regex)来验证输入并根据.checkValidity()状态采取行动。像下面这样的东西可以工作。在您的情况下,您需要一个正则表达式匹配长度。我的解决方案在此处在线使用/可演示。

1
2
3
4
5
6
7
8
9
10
11
<input type="text" pattern="[a-zA-Z]+" id="my-input">

var myInput = document.getElementById ="my-input";

myInput.addEventListener("keyup", function(){
  if(!this.checkValidity() || !this.value){
    submitButton.disabled = true;
  } else {
    submitButton.disabled = false;
  }
});

我用于IE 11且没有jquery且仅用于单个textarea的代码:

Javascript:

1
2
3
4
5
6
7
8
9
10
11
12
13
// Impede que o comentário tenha mais de num_max caracteres
var internalChange= 0; // important, prevent reenter
function limit_char(max)
{
    if (internalChange == 1)
    {
        internalChange= 0;
        return;
    }
    internalChange= 1;
    // <form> and <textarea> are the ID's of your form and textarea objects
    <form>.<textarea>.value= <form>.<textarea>.value.substring(0,max);
}

和html:

1
<TEXTAREA onpropertychange='limit_char(5)' ...

试试这个。这很简单,并且因为它是2016年,所以我确信它可以在大多数浏览器上使用。

1
2
3
4
5
6
7
8
<textarea id="text" cols="50" rows="5" onkeyup="check()" maxlength="15"></textarea>
<span id="spn"></span> characters left

function check(){
    var string = document.getElementById("url").value
    var left = 15 - string.length;
    document.getElementById("spn").innerHTML = left;
}


最好的办法是设置一个要在给定时间内调用的函数,然后使用此函数检查文本区域的内容。

1
self.setInterval('checkTextAreaValue()', 50);