How to identify a long press on arrow keys in jQuery - javascript

I have two options to myself keypress and keydown. I am inclined to use keypress because it records an event, even if the key is repeated i.e. key is long pressed. But the problem is that keypress records special keys such as arrow keys only in Firefox. If I want to do it cross browser then I have to use keydown but then a long press will be recorded as a single event.
Any help is appreciated.

var pressed = null;
$(element).on('keydown', function(event) {
pressed = +new Date();
// do whatever else you need upon key down
});
$(element).on('keyup', function(event) {
var duration = +new Date() - pressed;
pressed = null;
// do whatever you need to do based on the duration of the press
});
I leave it as an exercise to you to work out support for multiple concurrent keys pressed.

You could use two events, like so:
var timer=false,
pressedTime = 1000; //one second
$('input').on({
keydown: function(e) {
var charCode = (e.which) ? e.which : event.keyCode, keyP;
if (charCode===37) keyP = 'left';
if (charCode===38) keyP = 'up';
if (charCode===39) keyP = 'right';
if (charCode===40) keyP = 'down';
if (!timer) timer = setTimeout(function() {
clearTimeout(timer);
timer=false;
alert(keyP+' arrow key held down for 1 second');
}, pressedTime);
},
keyup: function() {
clearTimeout(timer);
timer=false;
}
});​
FIDDLE

there's a plugin named jQuery Responsiveness which may help achieving this.

Related

Adding keypressing events

I have a question. I have made a small site in HTML and vanilla JS to act as a counter. It is working fine, but I wanted to add a function that would allow the user to add or subtract 1 from the counter by pressing "+" or "-", in the numpad or not.
What is the easiest way to do this in vanilla JS?
Sure, just attach to the keyup events and increment or decrement the value when the proper key is pressed.
var value = 0;
document.addEventListener("DOMContentLoaded", function(event) {
document.querySelector(".valueHolder").innerHTML = value;
});
document.addEventListener("keyup", function(event) {
if (event.which == "187" || event.which == "107") { // + key
value++;
}
if (event.which == "189" || event.which == "109") { // - key
value--;
}
document.querySelector(".valueHolder").innerHTML = value;
console.log(event.which);
});
<div class="valueHolder"></div>
You will want to add an event listener on the document
document.addEventListener('keydown', myFunction);
function myFunction(e) {
var keyCode = e.keyCode();
...
}
You'll want to look up the keycodes for the keys you will be using (+ and -) and compare that value to keyCode. Then use a conditional to execute your adding or subtracting.
You would create an event handler, which would add or subtract from a global variable based on the key pressed, like this:
window.counter=0;
function key(ev){
if(ev.keycode==107) window.counter++;
if(ev.keycode==109) window.counter--;
}
document.onkeypress = key;

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);
}
});

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;
}
});

Noninterrupting keyevents while preserving individual keystrokes

I am designing a keyboard interface through javascript, and I want to define keystroke combinations, like shift+rightkey or ctrl+tab. But after tinkering with javascript, as seen here, I've noticed that all keyevents are interrupting. In the provided example, if you go to hit the shiftkey while holding down the rightkey, the functionality of the rightkey is interrupted!
v = 1; /*v is the variable of velocity.*/
window.addEventListener("keydown", function(event)
{
if(event.keyCode == 39) /*39 is the keycode of rightarrowkey.*/
{
//moves an element by the velocity.
var keystroke = document.getElementById("keystroke");
keystroke.style.left = parseInt(keystroke.style.left.slice(0,-2))+v+"px";
}
if(event.keyCode == 16) /*16 is the keycode of shift.*/
{
//increases the velocity of the element by four.
document.getElementById("keystroke").style.borderColor = "red";
v = 4;
}
}, false); //but hitting the shiftkey while hitting the rightkey interrupts..!
I also experimented with recording all keystrokes through an object which is then iterated through at a designated interval for defined keystrokes, as seen here. But this system of handling the keyboard doesn't preserve the individual keystrokes; if I hit a key too fast, it may not be considered, or if I hold a key for too long, it may be overconsidered!
After giving it a bit of thought, I may have figured out a method to both preserve each keystroke while handling interrupting keyevents. My code is somewhat quirky, but it works well for managing the keystrokes from the users.
The solution to handling each keystroke without interruptions was through registering each keyevent within an object, as was previously suggested in my question. The code continually iterates through this object to handle any new keyevents.
But to ensure each keystroke is preserved and handled at least once, a keybinding must be registered for each keyevent. I expanded the scripting for the object to register both keystrokes as well as keybindings.
var kbdin =
{
stroked: new Object(),
upbinded: new Object(),
downbinded: new Object(),
downbindKeystroke: function(keycode, functionality) {this.downbinded[keycode] = functionality;},
upbindKeystroke: function(keycode, functionality) {this.upbinded[keycode] = functionality;},
isDownbinded: function(keycode) {return this.downbinded[keycode];},
isUpbinded: function(keycode) {return this.upbinded[keycode];},
isStroked: function(keycode) {return this.stroked[keycode];},
onDownstroke: function(event)
{
var keycode = event.keyCode;
if(!this.isStroked(keycode))
{
this.stroked[keycode] = 1;
if(this.isDownbinded(keycode))
{this.downbinded[keycode]();}
}
if(this.isDownbinded(keycode))
{event.preventDefault();}
},
onUpstroke: function(event)
{
var keycode = event.keyCode;
delete this.stroked[keycode];
if(this.isUpbinded(keycode))
{
this.upbinded[keycode]();
event.preventDefault();
}
},
handleKeystrokes: function()
{
for(var keycode in this.downbinded)
{
if(this.isStroked(keycode) > 5)
{this.downbinded[keycode]();}
}
for(var keycode in this.stroked)
{this.stroked[keycode]++;}
}
};
document.addEventListener("keyup", function(event) {kbdin.onUpstroke(event);}, false);
document.addEventListener("keydown", function(event) {kbdin.onDownstroke(event);}, false);
window.setInterval(function() {kbdin.handleKeystrokes();}, 50);
Now both the keystrokes and keybindings are coupled together, supporting each keyevent with the functionality to both signal a keystroke and execute a keybinding. It may be a bit quirky, but this code handles noninterrupting keyevents while still preserving individual keystrokes!

How can I check that a key has been pressed?

Well I searched on Google but still didn't found the answer I was looking for.
I want to check if the user pressed a key, something like this -
if(document.onkeyup) {
// Some Stuff here
}
I know I can do this, this way -
document.onkeyup = getKey;
But the function getKey cannot return values.
So how can I check if the user pressed a key?
EDIT : I need pure Javascript for this thing..
You can do this in pure Javascript using the event object, without the need of external libraries such as jQuery.
To capture the keycode, just pass the event as parameter of getKey function:
function getKey(e)
{
window.alert("The key code is: " + e.keyCode);
}
document.onkeyup = getKey;
Frequently used keyCode list:
For a usefull list of keyCodes, you can check out this URL:
http://www.cambiaresearch.com/articles/15/javascript-char-codes-key-codes
Setting the keyCode to a global variable:
If you are interested in capturing the keyCode for later usage, you can do something like this:
var keycode = "";
(...)
function getKey(e)
{
keycode = e.keyCode;
}
document.onkeyup = getKey;
window.alert("The key code is: " + keycode);
Setting the keyCode to the event source object:
If you don't like global variables, like me, you could also do something like this:
function getKey(e)
{
keycode = e.keyCode;
var objectFromEvent = e.currentTarget ? e.currentTarget : event.srcElement;
objectFromEvent.customProperty = keycode;
}
document.customProperty = "";
document.onkeyup = getKey;
// now the value is in the "customProperty" of your object =)
window.alert("The key code is: " + document.customProperty);
One way you could do it is using variables
and then you could check that variable some were else...
for example
var keypressed = "";
document.onkeyup = function(e){
if (typeof event !== 'undefined') {
keypressed = event.keyCode;
}
else if (e) {
keypressed = e.which;
}
return false; // Prevents the default action
}
You really should not be doing this but if you really must:
var getKey = (function () {
var currentKey = null;
document.onkeyup = function (event) {
// determine the pressed key (across browsers)
// by inspecting appropriate properties of `event`
// and update currentKey; E.g:
currentkey = event.which ? event.which : window.event.keyCode;
}
return function () {
return currentkey;
}
})();
This will give you the last key user pressed.
If you need to get the currently pressed key (until released) then you need to attach keydown event to update currentKey variable and keyup event to set it to null.
You have to attach the event to the window global object and to set a function that listen to the event.
This sample show you how to track the keyup and keydown events.
window.addEventListener('keydown', onKeyDown, true);
window.addEventListener('keyup', onKeyUp, true);
function onKeyDown(evt) {
// key up event as been fired
console.log(evt.keyCode);
}
function onKeyUp(evt) {
// key up event as been fired
console.log(evt.keyCode);
}
See element.addEventListener on MDN for more details.
I would use jquery and do something like this:
// arrow keys click
$(document).keyup(function(e) {
// left arrow
if (e.keyCode == "37" ) {
// left stuff
// right arrow
} else if (e.keyCode == "39") {
// right stuff
// up arrow
} else if (e.keyCode == "38") {
// up stuff
// down arrow
} else if (e.keyCode == "40") {
// down stuff
}
});
etc, for the different key codes seen here http://www.cambiaresearch.com/articles/15/javascript-char-codes-key-codes
If you are attempting to run an event to test when a certain key is pressed, you can use this.
document.addEventListener('keydown', function(event) {
var key_code = event.keyCode;
if (key_code === 38) {
alert('test);
}
});

Categories