4

i have a textarea where i want to capture the necessary events either them be from the keyboard or the mouse/edit menu. Now, when a user copy pastes a text in the textarea through CTRL-V, processUserInput is called twice, both on keydown and on paste which is undesirable for various reasons.

i have "solved" it this way:

var IsProcessingEvent = false;
$("#textarea").on('click keydown cut paste', processUserInput);
function processUserInput(e) {
 if(!IsProcessingEvent) {
 IsProcessingEvent = true;
 // do the actual processing of user input
 IsProcessingEvent = false;
 }
}

I was wondering if there is a more elegant solution to this problem.

p.s the onpaste event is needed because the user may copy paste the text through the mouse right click or through the browser edit menu.

thanks in advance!

Sz.
3,7431 gold badge34 silver badges47 bronze badges
asked Jan 6, 2013 at 19:40
2
  • Not sure, but try to use event.stopPropagation() Commented Jan 6, 2013 at 20:14
  • @sdespont will not work because they are different events. It will stop keydown propagation then execute the past and stop it propagation too. Commented Jan 6, 2013 at 20:37

1 Answer 1

5

You are doing the right way dude. Just better if you change keydown for keypress, but you can get your code stylish if you want:

var isProcessingEvent = false;
$("#textarea").on('click keypress cut paste', processUserInput);
function processUserInput(e) {
 // Is processing event, so stop here.
 if(isProcessingEvent) {
 return;
 }
 isProcessingEvent = true;
 // do the actual processing of user input
 isProcessingEvent = false;
}

But if I would you, I will use a promisses to work with your processing of user input, that way you can not freeze all your UI Thread while wainting for the process.

Will be something like this:

$("#textarea").on('click keypress cut paste', processUserInput);
function processUserInput(e) {
 // Is processing event, so stop here.
 if(processUserInput.working) {
 // The user trigger the event while it was processing
 processUserInput.doAgain = {
 // save context
 ctx: this, 
 // save event
 e: e 
 };
 return;
 }
 processUserInput.working = true;
 function finished() {
 processUserInput.working = false;
 // The process finished but has new changes in the textfield so...
 var lastEvent = processUserInput.doAgain;
 if (lastEvent) {
 processUserInput.doAgain = null;
 // Process this guy again
 setTimeout(processUserInput.bind(lastEvent.ctx), 0, lastEvent.e);
 }
 }
 function theProcess(e, cb) {
 // do my async stuff here
 // Unfreeze the click/keydown/cut/past events in the textarea
 if (typeof cb === 'function') {
 cb();
 }
 }
 setTimeout(theProcess.bind(this), 0, e, finished);
}

This is a example for async, but you may use a async ajax, or web-worker to process your event, this way you would not freeze the UI Thread.

PS.: Timeout don't prevent UI Thread from freeze, it will just put your process in the end of the executing queue.

Ahh another tip!

If you are processing the text in the textarea, is better then you use keypress instead keydown because if you get the textarea value in the keydown it will not have changes, but the keypress will get the value changed by the key you are pressing.

http://www.quirksmode.org/dom/events/keys.html

Of course if you still want to use keydown you can defer the processing using the setTimeout that I made in the example.

answered Jan 6, 2013 at 20:19
Sign up to request clarification or add additional context in comments.

2 Comments

thanks for the tip. I'm using keydown, because i need to get data BEFORE the textarea changes, so all those events are fired BEFORE textarea data is changed. then with a timeout of 1ms i do more processing in the textarea after the data has changed.
@MIrrorMirror as I said in the begin, you are in the correct path my friend. I don't know how heavy is your process, but keep in mind that if is heavy, your users will thank you if you do it in web-worker or any other non-blocking solution. :)

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.