あなたは正しい方法でやっています。keydown
に変更した方が良いですがkeypress
、必要に応じてコードをスタイリッシュにすることができます。
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;
}
しかし、もしよろしければ、を使用しpromisses
てユーザー入力の処理を行います。そうすれば、プロセスを待機している間にすべての UI スレッドをフリーズすることはできません。
次のようになります。
$("#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);
}
これは非同期の例ですが、非同期 ajax または Web ワーカーを使用してイベントを処理することもできます。これにより、UI スレッドがフリーズしなくなります。
PS .: タイムアウトは UI スレッドのフリーズを妨げません。プロセスを実行中のキューの最後に置くだけです。
ああ、別のヒント!
テキストエリアのテキストを処理している場合は、keypress
代わりに使用するよりも優れkeydown
ています。キーダウンでテキストエリアの値を取得すると変更はありませんが、キーを押すと、押しているキーによって変更された値が取得されます。
http://www.quirksmode.org/dom/events/keys.html
もちろん、引き続き keydown を使用したい場合setTimeout
は、例で作成した を使用して処理を延期できます。