I'd like the value of two textareas to always be equal. Listening for a 'change' event is not sufficient because I want these fields to be equal even when one has focus. Listening for a keypress doesn't seem to work either as this event is fired before the field's value is updated with the new letter, so I'm not sure if there's a good way to get the current value of the field using a keypress handler in order to copy it over to the other field. Any ideas?
-
Similar: http://stackoverflow.com/questions/574941/best-way-to-track-onchange-as-you-type-in-input-typetext – gnarf Sep 20 '09 at 03:04
5 Answers
How about the keyup event?

- 183,342
- 71
- 393
- 434
-
3the `paste` event in IE and `input` event in FF are also worth mentioning – gnarf Sep 20 '09 at 03:03
-
-
1Unfortunately, this also captures arrow keys and the Tab key, where there isn't necessarily any change in the content. How do you address those? – Nikki Erwin Ramirez Nov 30 '10 at 11:52
-
I am having the same problem...
The value of a textarea can be changed by a lot of ways... i will mention only the ones i do not know how to detect:
- Mouse contextual Paste
- Keyboard contextual menu Paste
- Drag&Drop form other application, object, etc
- Shift Drag&Drop from same textare (dupes selected content at other position)
- Doing Ctrl+Insert - Shift+Insert (another way to Copy&Paste)
I had tried to create an event handler for every event i know (onkeyup, onkeydown, onmouseup, onmousedown, etc...) but with some of the previous ways of doing a Paste, no one is fired, so no way to control when occurs.
I see no other solution than placing a timer.
Ah! the content can also change without having the focus... cases of Drag&Drop.
And not to mention if also can be changed by JavaScript, the top mot ugly thing to dected... no method is fired!!!
I do not want to put a timer (that is very ugly to do things and potentionaly cause errors).
If timer is fired but another page is being loading (user clicked on a link)... you must control all objects exists... otherwise it will bring an error message (some browsers will show it as a modal window while other will ignore it)... so user gets a very poor impresion... and in the worst case... the call to your event handler can fail because your function was destroyed before timer call it.
With timers you allways must put on page unload, so get deactivated or destroyed when page is killed, for example when you go to another page.
This sort of things complicate much more than needed and are horrible to update in a future.
To ensure timers will not fail i do this sort of ugly thing as first sentence on it: clearTimeout(MyTimer);
And if i need the timer to repeat every X milliseconds... inside the function i do setTimeout(function(){MyFunction();)
In this way if things are destroyed in an inappropriate orther no error is cause by call to timer handler.
Also on every sentence inside the function MyFunction must be error controlated... any object being used must be ensure that exists... on every sentence... this is imposible to be done.. so a try catch must be added.
The other thing can be done when using timers is to ignore destroy problems and let the user get a very poor impression when page is unloaded.
To ensure no Timer is launched... the only thing i know is to ser the body onunload... but some ugly browers do not fire it (to avoid a programmer not letting you to go to another page)... so i must do things as if onunload does not exist... so timer can be called when objects are being destroyed... errors can occur allways...
So too tricky to ensure no error windows will bring up while using timers:
var MyTimer;
function MyTimer_Handler(){
try{
clearTimeout(TemporizadorCapaLogin);
try{
// Do whatever the timer must do
}Catch(theError){
// Your own code to control errors, but have in mind that while running the lines you write here can also cause error because while running this the objects get destroyed, so better not to put anything
}
MyTimer=setTimeout(function(){try{MyTimer_Handler()}Catch(theError){}},theIntervalToRepeatInMiliseconds);
}Catch(theError){}
}
try{MyTimer=setTimeout(function(){try{MyTimer_Handler()}Catch(theError){}},theIntervalToRepeatInMiliseconds);}Catch(theError){}
See what i am saying... too ugly code... but all trys are needed, else some browers can show an error message telling something does not exists when unload page occurs.
Well it is also worst, to really ensure you will try with this:
var MyTimer;
function MyTimer_Handler(){
try{
clearTimeout(TemporizadorCapaLogin);
try{
// Do only one sentence at a time
}Catch(theError){} // Ther is no way to ensure any line on Catch part can not cause an error because objects can have being destroyed before and while running this part
try{
// Do only one sentence at a time
}Catch(theError){} // Ther is no way to ensure any line on Catch part can not cause an error because objects can have being destroyed before and while running this part
// Repeat for each sentence
MyTimer=setTimeout(function(){try{MyTimer_Handler()}Catch(theError){}},theIntervalToRepeatInMiliseconds);
}Catch(theError){}
}
try{MyTimer=setTimeout(function(){try{MyTimer_Handler()}Catch(theError){}},theIntervalToRepeatInMiliseconds);}Catch(theError){}
But such secuence of Try{}Catch{} is the same as grouping all on one... so no benefit... as you can see Timers are very painfull to be used... just because there is no way to ensure no error will occur.
The cause is this secuence of events on some browsers:
- User asks for a page
- The page is downloaded
- The page activate a Timer
- The user clicks on a link or just close the tab... this causes the page to unload
- The browser starts destroy, object by object
- Before all are destroy the timer ir fired
- Code on timer is run, but some objects do not exists, have been destroyed
- While such code is running, browser continue destorying more objects (concurrently)
For example while is executed any line of code inside a timer, the JavaScript manager can be destroy on some browsers, and so it will fail and browser will present a modal window telling your page is baddly coded, the sentence can also be as simple as this: alert('bla bla bla');
Till now i did not find anyway to avoid such... execpt doing this on all timers:
var MyTimer;
function MyTimer_Handler(){
try{
clearTimeout(TemporizadorCapaLogin);
try{
// Do whatever the timer must do
}Catch(theError){}
MyTimer=setTimeout(function(){try{MyTimer_Handler()}Catch(theError){}},theIntervalToRepeatInMiliseconds);
}Catch(theError){}
}
try{MyTimer=setTimeout(function(){try{MyTimer_Handler()}Catch(theError){}},theIntervalToRepeatInMiliseconds);}Catch(theError){}
And it neither is a perfect solution... if the browser just destroy de JavaScript manager just when timer is fired but before the fisrt try (near a perfect milisecond sycn race condition) it also causes browser to present the message.
But since sometimes, somethings but be done after a while... not having a better / perfect solution, that is the best i can do!!
I personally hate such poorly coded browers (one of them is IE), but i must support them!!!

- 34,448
- 50
- 182
- 322

- 1,235
- 14
- 7
Browser-specific methods have been discussed here: onpropertychange for a textbox in Firefox?
However, after various experiments I found the only cross-browser method was to use window.setInterval() to check for changes (every 20 milliseconds, for example). Not elegant, but very effective.
//
function clonekeyup(e){
var e= window.event || e;
var who= e.target || e.srcElement;
var val= who.value;
var tem, temp, TA= document.getElementsByTagName('textarea'), L= TA.length;
while(L){
tem= TA[--L];
if(tem.onchange== arguments.callee && tem.value!= val) tem.value= val;
}
}
Assign the function onkeyup and onchange to the textareas you want to reflect each other. For instance, this assigns the handler to all the textareas.
var tem, TA= document.getElementsByTagName('textarea'), L= TA.length;
while(L){
tem= TA[--L];
tem.onkeyup= tem.onchange= clonekeyup;
}

- 102,654
- 32
- 106
- 127
Keyup does not work correctly when using shift+letter, but it works fine if you bind it to the window object.
Here's a jQuery plugin that takes advantage of it:
$.fn.edited = function(callback) {
this.each(function() {
var that = $(this);
var active = false;
that.focusin(function() {
active = true;
});
that.focusout(function() {
active = false;
});
$(window).keyup(function(e) {
if (active) {
callback(e);
}
});
});
};
Usage:
$("textarea").edited(function(){
...
});

- 18,293
- 11
- 75
- 82
-
Downvote because the question is asking about JavaScript, not CoffeeScript. – David Wolever Jul 14 '12 at 07:36
-