JavaScript execute until keypress - javascript

I want to execute a loop/action until a key is pressed and onpress I want to stop that action and call the function getKey. Can anybody suggest how to do this?
function getKey(e)
{
var pressedKey;
if (document.all) { e = window.event; }
if (document.layers || e.which) { pressedKey = e.which; }
pressedCharacter = String.fromCharCode(pressedKey).toLowerCase();
move(pressedCharacter);
}
document.onkeypress = getKey;
I want the move() function to be executing continuously till a key is not pressed . if it's pressed i want to re-execute the move() function with the new pressed character

Depends on how you loop. The easiest way is with an interval:
var interval = window.setInterval(function () {
// do your thing, do your thing
}, 1000);
document.onkeypress = function () {
if (/* some specific character was pressed */) {
window.clearInterval(interval);
// do some other thing, other thing
}
};

Use http://www.asquare.net/javascript/tests/KeyCode.html to find keycodes
<script>
document.onkeyup = getKey;
function getKey() {
// If the users hits 'a', stop loopcode from running.
if(event.keyCode == 65){
window.clearInterval(interval);
};
}
var interval = setInterval(function() {
// loopcode here
}, 1000);
</script>

Related

how to delay keypress enter

window.addEventListener('keydown', function(event) {
onKeyDownHandler(event);
}, false);
function onKeyDownHandler(e)
{
var focus_id = e.target.id;
switch (e.keyCode) {
case 13: // enter
if(focus_id == "Text1")
{
alert("function 1");
}else if(focus_id == "Text2")
{
alert("function 2");
}else if(focus_id == "Text3")
{
alert("function 3");
}
return;
}
}
is there anyway i can delay or make sure user dont spam by clicking the enter , how do i set keypress delay on my enter button ? which is the best way set delay timer or remove EventListener?
You can use the jQuery throttle/debounce plugin to only handle call your function when there is a pause in keyDown events.
You can prevent the default action for a period of time after the last Enter keypress:
window.addEventListener('keydown', onKeyDownHandler, false);
var lastEnter = null;
function onKeyDownHandler(e) {
var focus_id = e.target.id;
switch (e.which || e.keyCode) { // Note the e.which, for x-browser compat
case 13:
if (lastEnter && Date.now() - lastEnter < 5000) {
e.preventDefault();
return;
}
lastEnter = Date.now();
// Enter key processing...
break;
// ...other keys...
}
}
Or using jQuery (you've tagged your question jquery, but don't appear to be using jQuery in your code):
$(window).on("keydown", function(e) {
onKeyDownHandler(e);
});
var lastEnter = null;
function onKeyDownHandler(e) {
var focus_id = e.target.id;
switch (e.which) { // jQuery normalizes this for you
case 13:
if (lastEnter && Date.now() - lastEnter < 5000) {
e.preventDefault();
return;
}
lastEnter = Date.now();
// Enter key processing...
break;
// ...other keys...
}
}
Side notes:
Since the return value of an addEventListener callback is completely ignored and addEventListener calls the handler with just a single argument, if you're not using this within the handler (as you appear not to be), there's no need to wrap a function around onKeyDownHandler; just use it directly.
Some browsers use which for the keycode, others use keyCode, which is why I used e.which || e.keyCode in the switch. JavaScript's curiously-powerful || operator will use e.which if it's not falsey, e.keyCode otherwise.
You can create a timeout on enter press, and on another enter press, overwrite that previous timeout with the new one. That means that if you for example press enter again before the first timeout has ended, that first timeout will be overwritten by a new one, so that you get a new x amount of time before the actual timeout is executed. This works until infinity.
Example:
var keyup_timeout;
var timeout_delay_in_ms = 500;
element.on('keyup', function(e) {
e.preventDefault(); // Prevent default enter press action.
var enter_pressed;
if (e.which === 13) {
enter_pressed = true; // Just an example to illustrate what you could do.
}
if (enter_pressed) {
clearTimeout(keyup_timeout); // Clear the previous timeout so that it won't be executed any more. It will be overwritten by a new one below.
keyup_timeout = setTimeout(function() {
// Perform your magic here.
}, timeout_delay_in_ms);
}
});

Making a key pressed only register once rather than continually

I am developing a game where you must press the left and right arrow keys alternatively to make the character move, the faster you do it, the quicker he runs. I have however ran into a problem whereby the key is being "held down" in a sense so no matter how quick you press the key it still manages to execute it multiple times.
So I am looking for a way to make the key only be pressed once per press rather than updating if you hold down the key.
here is the code for my key capturing and what it executes at the moment (Which is just an update of points and an update of the image used for the character.
KEY_CODES = {
37: 'left',
39: 'right',
40: 'down',
}
KEY_STATUS = {};
for (code in KEY_CODES) {
KEY_STATUS[KEY_CODES[code]] = false;
}
document.onkeydown = function (e) {
var keyCode = (e.keyCode) ? e.keyCode : e.charCode;
if (KEY_CODES[keyCode]) {
e.preventDefault();
KEY_STATUS[KEY_CODES[keyCode]] = true;
}
}
document.onkeyup = function (e) {
var keyCode = (e.keyCode) ? e.keyCode : e.charCode;
if (KEY_CODES[keyCode]) {
e.preventDefault();
KEY_STATUS[KEY_CODES[keyCode]] = false;
}
}
function move() {
movecounter++;
// Determine if the action is move action
if (KEY_STATUS.left || KEY_STATUS.right ||
KEY_STATUS.down || KEY_STATUS.up) {
// Redraw the canavs background images ready for the new ones to be placed ontop.
paintCanvas();
// to have diagonal movement.
if (KEY_STATUS.left) {
ctx.drawImage(imageStore.snowWalk, playerPosW, playerPosH);
snowStand = true;
score += 10;
} else if (KEY_STATUS.right) {
ctx.drawImage(imageStore.snowWalk, playerPosW, playerPosH);
score += 10;
} else if (KEY_STATUS.down) {
ctx.drawImage(imageStore.snowCrouch, playerPosW, playerPosH);
snowStand = false;
}
}
};
Hope you understand the problem I am facing, I have tried to explain it as best as I can here.
Thanks!
A simple solution would be to have a variable outside of the scope of the event listener that tells you if you're pressing the key for the first time:
var pressed = false;
Then, in the listener, toggle the state of that variable when the key is pressed:
.keydown(function() {
if (pressed) return;
pressed = true;
}
.keyup(function() {
pressed = false;
}

Validate email on keyup and tab

I am success to handle user input on keyup but I have a problem to handle when the user press the tab key.
So this is my code so far:
var doneTypingInterval = 1000;
// Handle on keyup
$('#f-name').keyup(function() {
clearTimeout( typingTimer );
if($(this).val) {
typingTimer = setTimeout( doneTypingUsername, doneTypingInterval );
}
});
// Handle on tab-press
$('#f-name').on(function(e) {
var keyCode = e.keyCode || e.which;
clearTimeout( typingTimer );
if(keyCode == 9) {
e.preventDefault();
typingTimer = setTimeout( doneTypingUsername, doneTypingInterval );
}
});
// Error handler
function doneTypingUsername() {
if($('#f-name').val() == '') {
$('#f-name').siblings('.case1').fadeIn(500);
$('#f-name').siblings('.case2').hide();
valid_name_f = false;
} else {
if(!isValidUsername($('#f-name').val())) {
$('#f-name').siblings('.case1').hide();
$('#f-name').siblings('.case2').fadeIn(500);
valid_name_f = false;
} else {
$('#f-name').siblings('.case1').hide();
$('#f-name').siblings('.case2').hide();
valid_name_f = true;
set_name_timer = false;
}
}
checkForm();
}
As far as I run the code, it works fine. However, I think the way I handle the tab-press is not right. Since the keyup and tab-press will execute the same same thing, is there a better way to handle these two together?
Where your jquery says
$('#f-name').keyup(function() {
And
$('#f-name').on(function(e) {
You could be more efficient with
function functionName(e){
//do your timer and validation here
}
$(document).on('keyup', '#f-name', functionName(e));
$(document).on('blur', '#f-name', functionName(e));
Although this is not the cleanest solution, it should accomplish your email validation in both cases

Only be able to press space once every half a sec

When i press spacebar, the function shoot executes.
window.onkeydown=function(e){
var which = e.keyCode;
if(which == 32){
shoot();
}
}
If you hold space down, shoot calls many times in a row. I only want the function to execute once every 500ms.
(function($){
var lazerCharging = false,
lazerChargeTime = 500; // Charge time in ms
function handleKeyPress(e){
if(e.keyCode == 32){
shoot(lazerChargeTime);
}
}
function shoot(chargeTime){
if(!lazerCharging){
lazerCharging = true;
$("body").append("pew<br/>");
setTimeout(function(){
lazerCharging = false;
}, chargeTime)
}
}
$(window).on("keydown", handleKeyPress);
})($);
Here's a jsfiddle
You'll want to "debounce"
Using jQuery throttle / debounce, you can pass a delay and function to
$.debounce to get a new function, that when called repetitively,
executes the original function just once per "bunch" of calls.
This can be especially useful for rate limiting execution of handlers
on events that will trigger AJAX requests. Just take a look at this
example to see for yourself!
Ben Alman did the hard work for you here: http://benalman.com/code/projects/jquery-throttle-debounce/examples/debounce/
Essentially a debounce as MattC suggested. Store the time the function was called last and make sure 500 ms has passed. Also you probably should be using .addEventListener instead of window.onkeydown
(function() {
var lastCallTime = 0;
window.onkeydown = function(e){
var now = Date.now();
if(e.keyCode == 32 && now - lastCallTime > 500) {
shoot();
lastCallTime = now;
}
}
});
I doubt it's guaranteed that keydown/keypress events are always fired continuously. It may depend on the browser, operating system settings, etc. Even if they are, "fire rate" may fluctate. You probably don't want this.
I think a better idea would be to create a timer that's started when the first keydown event is fired, and stopped on keyup event.
http://jsfiddle.net/kPbLH/
var fireTimer = null;
function fire() {
// do whatever you need
}
document.addEventListener("keydown", function(e) {
if (e.keyCode == 32 && fireTimer === null) {
fire(); // fire immediately...
fireTimer = setInterval(fire, 500); // ...and 500ms, 1000ms and so on after
}
});
document.addEventListener("keyup", function(e) {
if (e.keyCode == 32 && fireTimer !== null) {
clearInterval(fireTimer);
fireTimer = null;
}
});

Javascript multiple keys depressed

so right now I'm using a function that will set a value to true if one key being pressed, another being pressed regardless of whether or not the first one is still depressed.
function doc_keyUp1(e) {
if (e.keyCode == 37){
lPunch = true
}
}
function doc_keyUp2(e) {
if (e.keyCode == 39){
rPunch = true
}
}
document.addEventListener('keyup', doc_keyUp1, false)
document.addEventListener('keyup', doc_keyUp2, false)
The thing is, I want to be able to have it make sure that if the second key is being pressed, that the first one must still be down, so that someone can't just press one then the other quickly and make it seem as if they were both pressed down at the same time.
Any ideas?
Assuming you have some kind of "game loop" something like the following works (or perhaps I should say "should work", in that I haven't coded something like this for a long time and so haven't tested it with current browsers - definitely used to work):
var keyPressed = {};
document.addEventListener('keydown', function(e) {
keyPressed[e.keyCode] = true;
}, false);
document.addEventListener('keyup', function(e) {
keyPressed[e.keyCode] = false;
}, false);
function gameLoop() {
if (keyPressed["39"] && keyPressed["37"]) {
// do something (update player object state, whatever)
}
// etc
// update display here
setTimeout(gameLoop, 5);
}
gameLoop();
I'd suggest you use an Array to hold key states.
var keyStates = [ ];
document.addEventListener('keydown', function(e) {
keyStates.push( e.keyCode );
}, false);
document.addEventListener('keyup', function(e) {
var pos = null;
if( (pos = keyStates.indexOf( e.keyCode )) > -1 )
keyStates.splice( pos, 1 );
}, false);
So with that, you can always check that array for keys currently beeing pushed.
var currentKeyCodes=new Object();
function keyDown(e) {
currentKeyCodes['x'+e.keyCode]=true;
}
function keyUp(e) {
//Real check here
if ((e.keyCode==39) && currentKeyCodes['x37']) {
do_whatever_you_want();
}
//Housekeeping
var s='x'+e.keyCode;
if (currentKeyCodes[s]) currentKeyCodes[2]=false;
}

Categories