Reputation: 1459
I am trying to build a UI that responses to keyPress event.
I am using Angular and RxJS to detect an event. [Packages are uptodate]
The code looks like
this.keyboard$ = Observable.fromEvent(document, 'keypress')
.pipe(debounceTime(300))
.subscribe(e => {console.log(e);})
This code works fine in a normal scenario, but the edge case when the user presses a key for too long this records the second press event once the key is released.
There is a work around that I found, but keyup defeats the purpose.
this.keyboard$ = Observable.fromEvent(document, 'keyup')
.pipe(debounceTime(300))
.subscribe(e => {console.log(e);})
I need to detect one event per keypress.
Can anyone please point out what is wrong with the snippet? Thanks in advance.
Upvotes: 1
Views: 6065
Reputation: 442
Actually its not a bug. When you hold a key, the browser resend the same event. Its Called Key Repeat.
Reference: https://developer.mozilla.org/en-US/docs/Web/Events/keypress
To avoid the Key Repeat, you could filter repeated events using the 'repeat' property.
const { fromEvent} = rxjs;
const {filter, map} = rxjs.operators;
var keyboard$ = fromEvent(document, 'keydown')
.pipe(filter(event => !event.repeat))
.subscribe(event => {
console.log(event.code);
})
Ive created a JSFiddle here so you can try it by yourself: https://jsfiddle.net/williamxsp/Lq9go1bt/
Upvotes: 5
Reputation: 265
I'm not familiar with Angular but I think it would look something like this:
have a variable which holds the key code of the most recently pressed key and another variable which will determine if the event will cause your function to be called. Each time a key is pressed call you function then don't allow your function to be called again until you hear a keyup event with the right code
var KeyUpHasOccurred = true;
var KeyCode;
this.keyboard$ = Observable.fromEvent(document, 'keydown')
.pipe(debounceTime(300))
.subscribe(e => {
if(KeyUpHasOccurred)
console.log(e);
KeyUpHasOccurred = false;
KeyCode = e.key
})
this.keyboard$ = Observable.fromEvent(document, 'keyup')
.pipe(debounceTime(300))
.subscribe(e => {
if(e.key = KeyCode)
KeyUpHasOccurred = true;
})
Upvotes: 1