Change character when keydown is held - javascript

I am trying to make a simple way to change a character in an input field when the key is held down for more than 1second. For example holding down a would then change the character to á.
The exact thing I am looking to do can be seen on fluencia.com.
Also there is a need to be able to change the character if it is held for a further second.
So far, all I have done is detect the key held with the following code:
count = 0;
$(document).bind('keypress', function(e){
keyisdown = false;
key = e.which
if (e.which === key) {
keyisdown = true;
count ++;
if(count>1){
}
}
}).bind('keyup',function(){
keyisdown = false;
count = 0;
console.log('key up');
});
Thanks
Adam

This should do it for key "a".. You'll need to look up your keycode
var fired = false;
$(document).on("keydown", function(e) {
if (e.keyCode == 65) {
var timer = setTimeout(function() {
if (!fired) console.log('its held');
fired = true;
}, 1000);
$(document).on("keyup", function() {
clearTimeout(timer);
});
}
});
fiddle - http://jsfiddle.net/0a9rftt2/

With help from Graham T above and a bit of playing around I come up with the following:
var fired = false;
var keycode = null;
var key = null;
$("#loginEmail").on("keypress", function(e) {
keycode = e.which;
key = String.fromCharCode(keycode);
});
$("#loginEmail").on("keydown", function(e) {
var s = this.value;
var str = this.value;
if (e.keyCode == 65) {
var timer = setTimeout(function() {
if (!fired) console.log('its held');
fired = true;
if(fired){
s = $("#loginEmail").val();
str = s.substring(0, s.length - 1);
replacewith = 'á';
str = str+replacewith;
$("#loginEmail").val(str);
}
}, 500);
$(document).on("keyup", function() {
clearTimeout(timer);
fired = false;
});
}
});
It is not cleaned up as yet. I had to use keypress to get the true character (capitalised or not) and then used keydown to detect key being held down.

Related

Manipulating integers using a keyboard

Sorry for the vague post. I'm stuck on an online coding challenge, where the objective is that it must be possible to increase and or decrease a number using a keyboard, using the up and down keys. (all HTML-content must be created using JS)
It wants me to use addEventListener without an element object - use the event type keydown. Regardless if the buttons or the up and down keys are used, the decrease button must be 'disabled' if the values in the div-element is '1', and there can't be a number less than '1' in the div element.
Here is my code so far - I'm not sure how to incorporate the functions described above:
addEventListener('load', function() {
let button = document.createElement('input')
let secondButton = document.createElement('input')
button.setAttribute('type', 'button')
button.setAttribute('id', 'increase')
secondButton.setAttribute('type', 'button')
secondButton.setAttribute('id', 'decrease')
document.body.appendChild(button)
document.body.appendChild(secondButton)
let div = document.createElement('div')
div.setAttribute('id', 'bet-size')
div.textContent = '1'
document.body.appendChild(div)
if (Number(div.textContent) === 1) {
secondButton.setAttribute('disabled', '')
}
const increase = function() {
div.textContent = Number(div.textContent) + 1
if (Number(div.textContent) > 1) {
secondButton.disabled = false
}
}
const decrease = function() {
if (Number(div.textContent) === 2) {
secondButton.disabled = true
}
if (Number(div.textContent) > 1) {
div.textContent = Number(div.textContent) - 1
}
}
button.addEventListener('click', increase)
secondButton.addEventListener('click', decrease)
})
You want to use keyDown event's keyCode property to determine the pressed key and call increase() or decrease() accordingly. keyCode stores a number indicating the key that caused the event evocation. There are a number of sites on the internet to determine your desired key code, like this for example.
You also might want to use keyUp to determine key releases again because you might get these events multiple times and only want to react to one of them.
let isKeyDown = false;
const handleKeyDown = function(event) {
if(isKeyDown == false)
{
isKeyDown = true;
if(event.keyCode == 38) // Arrow Up
{
event.preventDefault(); // Prevent page scrolling
increase();
}
else if(event.keyCode == 40) // Arrow Down
{
event.preventDefault(); // Prevent page scrolling
decrease();
}
}
}
const handleKeyUp = function(event) {
if(isKeyDown == true)
{
isKeyDown = false;
}
}
document.addEventListener('keydown', handleKeyDown);
document.addEventListener('keyup', handleKeyUp);
Your expanded example might look like this, then:
addEventListener('load', function() {
let button = document.createElement('input')
let secondButton = document.createElement('input')
button.setAttribute('type', 'button')
button.setAttribute('id', 'increase')
secondButton.setAttribute('type', 'button')
secondButton.setAttribute('id', 'decrease')
document.body.appendChild(button)
document.body.appendChild(secondButton)
let div = document.createElement('div')
div.setAttribute('id', 'bet-size')
div.textContent = '1'
document.body.appendChild(div)
if (Number(div.textContent) === 1 ) {
secondButton.setAttribute('disabled', '')
}
const increase = function() {
div.textContent = Number(div.textContent) + 1
if (Number(div.textContent) > 1) {
secondButton.disabled = false
}
}
const decrease = function() {
if (Number(div.textContent) === 2) {
secondButton.disabled = true
}
if (Number(div.textContent) > 1) {
div.textContent = Number(div.textContent) - 1
}
}
// Required to remember if a key is already pressed or not
let isKeyDown = false;
//Event handlers for KeyUp And KeyDown
const handleKeyDown = function(event) {
if(isKeyDown == false)
{
isKeyDown = true;
if(event.keyCode == 38) // Up
{
event.preventDefault(); // Prevent page scrolling
increase();
}
else if(event.keyCode == 40) // Down
{
event.preventDefault(); // Prevent page scrolling
decrease();
}
}
}
const handleKeyUp = function(event) {
if(isKeyDown == true)
{
isKeyDown = false;
}
}
button.addEventListener('click', increase)
secondButton.addEventListener('click', decrease)
//Add the new event handlers to the document's keydown and keyup events
document.addEventListener('keydown', handleKeyDown);
document.addEventListener('keyup', handleKeyUp);
})

How to handle pressing C+/ keys on JS(key combination) and invoke some function?

const cKeycode = 67;
const SlashKeyCode = 191;
document.onkeyup = function(e){
var e = e || window.event;
if(e.keyCode==cKeycode && e.which == SlashKeyCode) {
alert("C+/ pressed");
return false;
}
}
I've just tried this one and many other variants but I can't handle this. Maybe someone know the better way
Your code doesn't work because the event only passes one key at a time (excluding keys like ctrl and alt). To get around this, we can store if either key is pressed, then check this once the second key is pressed. This method works whether the user presses c then /, or if they press / then c.
const keys = ["c", "/"];
var pressedKey = -1;
document.onkeydown = function(e){
var e = e || window.event;
let key = e.key;
if (keys.indexOf(key) > -1) {
if (pressedKey === -1) pressedKey = key;
else if (pressedKey !== key) console.log("C + / pressed");
}
}
document.onkeyup = function(e) {
let key = e.key;
if (key === pressedKey) pressedKey = -1;
}
The onkeyup event doesn't return a collection of pressed keys - it just returns a single key at a time. Furthermore onkeyup just fires if you actually release a key so if you want to know when two keys are pressed you need to utilize the onkeydown event.
To do this create a global boolean variable which states if the first button is actually pressed and if it is, check if the second key is pressed as well.
Here's an example. For simplicity I'm using the a and e key.
const AKeycode = 65;
const EKeycode = 69;
let AKeycodeDown = false;
let EKeycodeDown = false;
document.onkeydown = function(e) {
if (e.keyCode == AKeycode) {
AKeycodeDown = true;
}
if (e.keyCode == EKeycode) {
EKeycodeDown = true;
}
if (AKeycodeDown && e.keyCode == EKeycode || EKeycodeDown && e.keyCode == AKeycode) {
AKeycodeDown = false;
EKeycodeDown = false;
alert("A+E pressed");
}
}
document.onkeyup = function(e) {
if (e.keyCode == AKeycode) {
AKeycodeDown = false;
}
if (e.keyCode == EKeycode) {
EKeycodeDown = false;
}
}

Key pressed and click in the same time

how can I merge keypress and on click? I mean when a user press enter and click somewhere in the same time I need to invoke a function.
$(document).keypress(function(e) {
var code = e.keyCode || e.which;
if(code == 13) {
alert('keypress');
}
});
$(document).on( "click", function() {
alert('click');
});
I have this code but I am not able to merge it (usually I don't work with jQuery/javascript).
Something like this may do the trick
var pressingEnter = false;
$(document).on({
keydown: function(e) {
if(e.which == 13) {
// enter is being pressed, set true to flag variable
pressingEnter = true;
}
},
keyup: function(e) {
if(e.which == 13) {
// enter is no longer pressed, set false to flag variable
pressingEnter = false;
}
},
click: function() {
if (pressingEnter) {
console.log('click and enter pressed');
}
}
});
BTW: there is no need to do var code = e.keyCode || e.which; since jQuery resolves that for you. You can use e.which on any browser.
EDIT
This version should allow any order of key pressed / mouse click. I'm assuming only left click is captured. Logic to handle enter + mouse click is placed on keydown and mousedown (it could be moved to keyup and mouseup if makes more sense)
Changed alert by console.log since the first prevents mouseup event to be triggered. Nowdays we have hundred of better ways to show a message to user than built-in alert pop ups so I'll assume making it work for it is not a requirement.
var pressingEnter = false;
var clickingMouseButton = false;
$(document).on({
keydown: function(e) {
if(e.which == 13) {
pressingEnter = true;
}
if (clickAndEnterPressing()) {
console.log('click and enter pressed');
}
},
keyup: function(e) {
if(e.which == 13) {
pressingEnter = false;
}
},
mousedown: function(e) {
if (e.which == 1) {
clickingMouseButton = true;
}
if (clickAndEnterPressing()) {
console.log('click and enter pressed');
}
},
mouseup: function(e) {
if (e.which == 1) {
clickingMouseButton = false;
}
}
});
function clickAndEnterPressing() {
return pressingEnter && clickingMouseButton;
}
Here's an example that will work if enter is pushed first or if the mouse is clicked first or if they are both pressed within a certain threshold of time apart (I set it to 100 ms, but this can be easily adjusted):
var enterDown = false;
var mouseDown = false;
var lastEnter = false;
var lastMouseUp = false;
var triggerOnNextUp = false;
$(document).on({
keydown: function(e) {
enterDown = true;
},
keyup: function(e) {
if(e.which == 13) {
lastEnter = (new Date()).getTime();
enterDown = false;
detectEnterAndClick();
if (mouseDown) {
triggerOnNextUp = true;
}
}
},
mousedown: function() {
mouseDown = true;
},
mouseup: function() {
lastMouseUp = (new Date()).getTime();
mouseDown = false;
detectEnterAndClick();
if (enterDown) {
triggerOnNextUp = true;
}
}
});
function detectEnterAndClick() {
if (Math.abs(lastEnter - lastMouseUp) < 100 || triggerOnNextUp) {
// Reset variables to prevent from firing twice
triggerOnNextUp = false;
enterDown = false;
mouseDown = false;
lastEnter = false;
lastMouseUp = false;
$("body").append("Clicked and pushed enter<br>");
}
}
See it on JSFiddle
There is no way to 'merge' events. However you could for example debounce your handler. For example (using lodash):
var handler = _.debounce(function(event) { alert(event.type); }, 100);
$(document)
.on('click', handler)
.on('keypress', handler);
you can use the event.type to determine what triggered the event
Demo
$(function(){
$(document).on("click", ClickAndKeyPress);
$(document).on("keypress", ClickAndKeyPress);
});
function ClickAndKeyPress(event){
$("div").text(event.type);
}

How to know which key was held when left mouse button was clicked?

I wan't to detect if some other key is held when the left mouse button is clicked how can i do it?
i used this to detect ctrl+shift but now i wan't to know if 'A' or 'B' or both were held.
if(e.shiftKey && e.ctrlKey) console.log("ctrl+shift key was held when pressing the left mouse button");
the mouse event I receive doesn't have a keyCode for held keys. I want pure Javascript.
Maybe something like this (listening for keydown and keyup):
var keys = [];
$(document).keydown(function(e){
var index = keys.indexOf(e.keyCode);
if(index === -1){
keys.push(e.keyCode);
}
}).keyup(function(e){
var index = keys.indexOf(e.keyCode);
if(index !== -1){
keys.splice(index, 1);
}
}).click(function(e){
console.log(keys);
});
A pure javascript solution would be:
var held_key = null;
function key_down(event) {
var key = event.keyCode || event.which;
// get string representation of held key
var keychar = String.fromCharCode(key);
// store held key in global variable
held_key = keychar;
}
//revert held_key to null onkeyup
function key_up(event) {
var key = event.keyCode || event.which;
held_key = null;
}
window.onload = function() {
window.onkeydown = key_down;
window.onkeyup = key_up;
window.onclick = function(e) {
// put condition for the key you want here
if (held_key == 'A') {
//do something
console.log('hi!');
}
}
}

Javascript - Check if key was pressed twice within 5 secs

I want to check if Enter key was pressed twice within 5 secs and perform some action.
How can I check if the key was pressed once or twice within a given time and perform different actions.
Here is my code:
<h1 id="log">0</h1>
<br/>
<span id="enteredTime">0</span>
<script>
$(document).keypress(function(e) {
if(e.which == 13){
var element = $("#log");
var timeDifference = 0;
//Log the timestamp after pressing Enter
$("#enteredTime").text(new Date().getTime());
//Check if enter was pressed earlier
if ($("#enteredTime").text() !== "0") {
var now = new Date().getTime();
var previous = $("#enteredTime").text();
difference = now - previous;
}
//Check if enter was pressed only once within 5 secs or more
if(){
$("#log").text("Once");
$("#enteredTime").text("0");
//Check if enter was pressed twice in 5 secs
}else{
$("#log").text("Twice in less than 5 secs");
$("#enteredTime").text("0");
}
}
});
</script>
http://jsfiddle.net/Rjr4g/
Thanks!
something like
var start=0;
$(document).keyup(function(e) {
if(e.keyCode == 13) {
elapsed = new Date().getTime();
if(elapsed-start<=5000){
//do something;
}
else{
//do something else;
}
start=elapsed;
}
});
Try a timer based solution like
var flag = false,
timer;
$(document).keypress(function (e) {
var element = $("#log");
var timeDifference = 0;
if (e.which == 13) {
if (flag) {
console.log('second');
clearTimeout(timer);
flag = false;
} else {
console.log('first');
flag = true;
timer = setTimeout(function () {
flag = false;
console.log('timeout')
}, 5000);
}
//Log the timestamp after pressing Enter
$("#enteredTime").text(new Date().getTime());
if ($("#enteredTime").text() !== "0") {
var now = new Date().getTime();
var previous = $("#enteredTime").text();
difference = now - previous;
}
}
});
Demo: Fiddle
Bacon.js seems like a good tool to express this.
$(document).asEventStream('keypress')
.filter(function (x) {
return x.keyCode == 13;
})
.map(function () {
return new Date().getTime();
})
.slidingWindow(2, 1)
.map(function (x) {
return (x.length == 1 || x[1] - x[0] > 5000) ? 1 : 2;
})
.onValue(function (x) {
$("#log").text(x == 1 ? "Once" : "Twice in less than 5 secs");
});
(fiddle)
here is my solutions, please check it if match your idea :)
(function($){
var element = $("#log");
var timeDifference = 0;
var count = 0;
$(document).keypress(function(e) {
if(e.which === 13){
//do what you want when enterpress 1st time
/*blah blah */
//after done 1st click
count++;
if(count === 2) {
//do what you want when enterpress 2nd time in 5 seconds
/* blah blah */
//after done
clearTimeout(watcher);
count = 0;
return;
}
//setTimeout to reset count if more than 5 seconds.
var watcher = setTimeout( function() {
count = 0;
},5000);
}
});
}(jQuery)
Check your Updated Fiddle
var count = 0;
$(document).keypress(function(e) {
var element = $("#log");
var timeDifference = 0;
if(e.which == 13){
count++;
console.log('enter pressed'+count);
if(count == 1){
startTimer();
}
else{
checkCount();
}
//Log the timestamp after pressing Enter
$("#enteredTime").text(new Date().getTime());
if ($("#enteredTime").text() !== "0") {
var now = new Date().getTime();
var previous = $("#enteredTime").text();
difference = now - previous;
}
}
});
function startTimer(){
setTimeout(checkCount,5000);
}
function checkCount(){
if(count == 1){
$("#log").text("Once");
$("#enteredTime").text("0");
//Check if enter was pressed twice in 5 secs
}else{
$("#log").text("Twice in less than 5 secs");
$("#enteredTime").text("0");
}
}
startTimer() starts counting on first enter press. And checkCount() contains your condition after 5secs.
setTimeout() lets you attach an event which occurs after a specific timespan.

Categories