Back in college I wrote a game where the computer would sleep for 1 second, wake up and check to see if anything needed to be processed.
Of course, if the user entered a single character command, it would respond immediately.
Is there a way to do that with JavaScript?
setTimeout() and setInterval() will allow you to execute some code at regular intervals.
You can also monitor key press events in the DOM. Libraries like jQuery make this really easy with built in support for keyDown, keyUp and keyPress events. You can see these here: http://docs.jquery.com/Events
function processKeyCommand(){
...
}
document.onkeypress = processKeyCommand
function processEverythingEveryOneSecond(){
...
setTimeout(function(){processEverythingEveryOneSecond()}, 1000)
}
processEverythingEveryOneSecond()
:))
Related
I'm creating an input field where some data should be fetched (by AJAX) and displayed every time the user enters data into that field. However, if the user types several characters, say he types "test" to get all records who contain the string "test", it would not be necessary to do 4 queries after every character pressed, but one query after he stopped typing. I can think of several solutions with a global variable where I check if the same event has been fired again, but is there a really elegant way to do this? Maybe check if there is something in the keyboard buffer and only proceed if it is empty? Or is there an event that is only fired once the keyboard buffer is empty and all characters are in the input field?
The elegant way is to use a timeout, and to keep clearing the previous timeout with each key press
var tID;
function keyUp (e) {
if (tID) clearTimeout(tID);
tID = setTimeout(function() {
... // make web call
}, 2000);
}
This will ensure that the web call is only called after the last key is pressed (you may want to adjust the timeout value)
There are ways to achieve this that I can think of:
Use timeout, from the last keyup event. This is not always the best and not that precise with users that have low typing speed.
Use space character do regconize if the user has finished typing a word. Based on changes in length and total word count, you can decide if you would want to send AJAX or not.
Depends on the type of input you are working with, you may choose the most suitable method for you. The first one is somewhat quite rigid. The second method requires user to press space every time he finishs typing. A little bit of both could be a sweet spot perhaps. In modern day, I don't think sending request every keyup will cause huge performance effect though.
I have a input textbox for people to enter a username, it has a onkeyup event attribute attached which fires off an AJAX request to check if the username is taken.
What is the delay between the first key to the second ? Meaning if I type a 5 letter word one letter after the other. Does the AJAX fire 5 times ?
If there is no delay, would this be "computationally expensive" since there would so many database queries ? Or would there be no noticeable difference ?
If there is a difference in performance, what methods could I take using Javascript to check if the user is actually "done" typing. I still want it to automatically check after typing. Thus ruling out onblur attributes etc.
My Code: http://pastebin.com/hXfgk7nL
(code indentation wasn't working for me on stack overflow)
Yes it will fire EVERYTIME you type a character and you're not going to like that in terms of your page performance. You can implement delays on executing the call back if you like ie. it will not be executed until the user stopped typing. Here's an example:
$(document).ready(function(){
$('#txtboxid').keyup(function(){
clearTimeout(timer);
timer = setTimeout(function(){
//call your function here
}, 250) // you can change the 250 here to a higher number if you want the delay to be longer. In this case, 250 means a quarter of a second.
});});
Following are my replies/suggestion for your queries:
Yes , it will fire 5 fives because 5 times key-up event will be triggered.
it will be a performance issue, resulting in slow response from server,also since your making multiple ajax request sequentially, the response from each request may not be sequential.your code will suffer from logic issue.
instead of making ajax call for key-up, you can use it for blur event.
Suggestion: before making a ajax call validate the field for basic errors like blank string, numbers etc.,(depending on your requirement).
Yes it will fire multiple times, one for each keystroke. You are triggering multiple AJAX calls, so you are wasting network and server resources.
Additionally, you are not guaranteed on the order in which the calls will return, so if for some network reason, the first call issued return last, it will overwrite the results of the most recent request.
To tackle the problem, you are looking for something like this plugin: https://github.com/cowboy/jquery-throttle-debounce.
From the plugin usage example:
function ajax_lookup( event ) {
// Perform an AJAX lookup on $(this).val();
};
// Console logging happens on keyup, for every single key
// pressed, which is WAAAY more often than you want it to.
$('input:text').keyup( ajax_lookup );
// Console logging happens on window keyup, but only after
// the user has stopped typing for 250ms.
$('input:text').keyup( $.debounce( 250, ajax_lookup ) );
Note that despite the name the plugin can also be used stand alone, without jquery.
Yes, it will fire every key-up event. You can reduce the performance hit using following approach.
I am sure you must have a minimum character length for username. Wait until user type that number of characters to query the database.
You could always bring all the usernames starting with user typed username and process in local memory. This may not be real time but would reduce the number database queries. Also it would depend on the size of your current user list.
Double check the existence of the username before saving it to the database.
yes it will fire. if you don't need that means, you have to check conditions with a flag. check the given value with the previous value which is stored in a variable.
You can try to check if your input is modified in 500 ms. Is is not, then make only one ajax request. If the input is modified again than you must repeat the process again.
I suggest to use setInterval for that.
working on a dynamic request as a person types.
Would like to try to throttle it so not EVERY key press fires off a call.
First thought was to do a setimeout of 1s and clear the timeout with each keypress, therefore waiting till there is a lag of 1s before pushing off the request.
Wondering if there are any cleaner suggestions
Underscore.js Offers a throttle function that creates a version of a function that is executed only once every x milliseconds. You might want to look into that
That solution will work well if you don't have a lot of other script that will run simultaneous.
Otherwise you can set up an if loop which triggers the call every 5 keypress for example.
Something like this:
if(i == 5) {
//Execute your call
}
And then you you increase the value of i each time a key is pressed.
But of course there are even more solutions as well.
Ok, so I trying to achieve a console-like behavior and I need to pause the execution until some event is dispatched, what I exactly need is this:
var evt = $("element").waitForKeyDown();
This hypothetical function should pause the execution until the user presses a key on the "element" element, which is supossed to be a textfield. Then when the user presses any key on that textfield, the execution should continue and evt should contain the information related to that event.
Is this possible to achieve in javascript? or a close behavior that works like.
You don't ever want to wait in JavaScript--there's only one thread, and you need it available to handle other events that may be coming in to other parts of the page.
What you want to do instead is take everything that's supposed to happen after the point where you want to wait and package it up into a function(){}. (This function is called a "continuation" and you'll encounter this pattern all over the place in JavaScript and other heavily asynchronous environments.)
From there, you'll register your new function using the following jQuery:
var evt = $("element").keydown(function(event){
var keypressed = event.keyCode;
// do whatever you'd like with the keypress.
});
You could consider using keypress instead of keydown, but keypress (almost paradoxically) doesn't get you all keypresses, just those that turn into text input of some sort.
I'm afraid there are no blocking actions in javascript, except alert and prompt. The only way to do this is (could be wrong though):
var evt = $("element").on("click",function(){
//Continue here
});
just use the keydown event. it does exactly what you want to achieve: do an action only when a key has been pressed.
Use jQuery .keyDown http://api.jquery.com/keydown/
var evt = $("element").keyDown(function(){
//Rest of your code
});
I want to develop a simple app to measure dwell time and flight time (see http://www.techrepublic.com/article/reduce-multi-factor-authentication-costs-with-behavioral-biometrics/6150761) in a text area / box. how can I use keypress() or keydown() up() methods to record these events?
I don't understand why this would not be worth it. Just because Javascript can be modified on the client side does not mean an attacker could reproduce an actual user's typing patterns.
Doing this on the client side has the added benefit of keeping the user's data private (e.g. you're not actually collecting user's keystrokes, but only information related to their typing patterns).
I'm sure there are still privacy concerns, but this is a very interesting authentication (or auditing/detection) control.
See an example here: http://jsfiddle.net/VDMPt/ source
But as Andrea said, is not worth it since Javascript is client side
var xTriggered = 0;
$('#target').keyup(function(event) {
if (event.keyCode == '13') {
event.preventDefault();
}
xTriggered++;
var msg = 'Handler for .keyup() called ' + xTriggered + ' time(s).';
$.print(msg, 'html');
$.print(event);
});
$('#other').click(function() {
$('#target').keyup();
});
I believe this approach would not be fruitful in a real-world environment, because whatever processing you do in Javascript is, in line of principle, easily modifiable by the user, by using a simple javascript debugger or programs like Firebug.
That said, you could measure the two metrics in this way:
dwell time = time between keydown() and keyup(). In your keydown() method save the current time and in the keyup() compute the twell time as the difference between the current time and the keydown() time.
flight time: from the figure of the article you linked I can't easily understand how it is defined, but I would compute it as the difference between when you left the last key (keyup()) and when you start pressing the next key (keydown()). So in keyup() save a time, for instance last_key_time, and in keydown() compute the flight time as current_time - last_key_time