Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Textarea onchange detection

Tags:

javascript

People also ask

What can I use instead of Onchange?

Try using the input event.

How can I bind to the change event of a textarea in jQuery?

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

Which is not event of textarea?

Unfortunately, FF does not fire change event for textarea .

How do I get text from textarea?

Use the value property to get the value of a textarea, e.g. const value = textarea. value . The value property can be used to read and set the value of a textarea element. If the textarea is empty, an empty string is returned.


The best way to do this, cross-browser: use a combination of the input and onpropertychange events, like so:

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
  });
}

The input event takes care of IE9+, FF, Chrome, Opera and Safari, and onpropertychange takes care of IE8 (it also works with IE6 and 7, but there are some bugs).

The advantage of using input and onpropertychange is that they don't fire unnecessarily (like when pressing the Ctrl or Shift keys); so if you wish to run a relatively expensive operation when the textarea contents change, this is the way to go.

Now IE, as always, does a half-assed job of supporting this: neither input nor onpropertychange fires in IE when characters are deleted from the textarea. So if you need to handle deletion of characters in IE, use keypress (as opposed to using keyup / keydown, because they fire only once even if the user presses and holds a key down).

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

EDIT: It seems even the above solution is not perfect, as rightly pointed out in the comments: the presence of the addEventListener property on the textarea does not imply you're working with a sane browser; similarly the presence of the attachEvent property does not imply IE. If you want your code to be really air-tight, you should consider changing that. See Tim Down's comment for pointers.


You will need to use onkeyup and onchange for this. The onchange will prevent context-menu pasting, and the onkeyup will fire for every keystroke.

See my answer on How to impose maxlength on textArea for a code sample.


  • For Google-Chrome, oninput will be sufficient (Tested on Windows 7 with Version 22.0.1229.94 m).
  • For IE 9, oninput will catch everything except cut via contextmenu and backspace.
  • For IE 8, onpropertychange is required to catch pasting in addition to oninput.
  • For IE 9 + 8, onkeyup is required to catch backspace.
  • For IE 9 + 8, onmousemove is the only way I found to catch cutting via contextmenu

Not tested on 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>

I know this isn't exactly your question but I thought this might be useful. For certain applications it is nice to have the change function fire not every single time a key is pressed. This can be achieved with something like this:

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

This works by testing if a more recent event has fired within a certain delay period. Good luck!