How does one go about attaching a bunch of code to an onkeydown
event, but keep entering text into a textarea
fast and crisp? Anything more than a couple of IF statements seems to slow it down quite considerably.
EDIT: I should add (can't believe I forgot!) that this doesn't affect desktop browsers. It's mainly an issue with iPhone Safari. Other mobile browsers might be affected as well, but we're focusing on iPhone Safari since it executes JS the best (AFAIK)
Considering your edit regarding this being focused on iPhone access...
The iPhone really just doesn't have that much power to it. You'll be better off just using onchange
or onblur
instead of onkeydown
.
An alternative to Dave's answer is waiting for the user to pause (e.g. for 5 seconds):
var textarea = document.getElementById('textarea');
function checkTextArea() {
if (textarea.value /* ... */) {
/* ... */
}
}
textarea.keyDownTimeout = null;
textarea.onkeydown = function () {
if (textarea.keyDownTimeout) clearTimeout(textarea.keyDownTimeout);
textarea.keyDownTimeout = setTimeout(checkTextArea, 5000);
};
This should set the timer with the first keydown, stopping and recreating the timer for each successive keydown. Finally calling 5 seconds after the user stops typing.
Also, note the lack of parenthesis after checkTextArea
. This will give setTimeout
the function's reference vs. its return
.
You can also set this up in a function to make it easier to use for multiple elements:
function setPauseTimer(element, timeout, callback) {
var timer = null;
element.onkeydown = function () {
if (timer) clearTimeout(timer);
timer = setTimeout(function(){ callback(element); }, timeout);
};
}
function checkTextArea(textarea) { /* moved from global to argument */
if (textarea.value /* ... */) {
/* ... */
}
}
setPauseTimer(document.getElementById('textarea'), 5000, checkTextArea);
Maybe you could post "a bunch of code" and we could discuss whether there's some refactoring there (before complexifying it with a timer). It seems like you might be jumping to secondary optimizations first.
Well, one way to go would be not using onkeydown, but using a timer instead. You can set an interval running a function checking the contents of the TextArea and run your logic there. It seems it would by pass most of the overhead. Anyway, give it a shot, I think it might help.
Here's how you would use it:
// First param is the function to call, second is
// time interval in miliseconds
var timer = setTimeout(checkTextArea(), 5000);
function checkTextArea() {
var text = document.getElementById("textarea").value;
// logic...
timer = setTimeout(checkTextArea(), 5000); // we loop it back to
//the function with the timer
}
I had thought of the timer methods. I believe setTnterval
would be better than a setTimeout
, but that hardly seems an optimum solution, doesn't it?