我正在尝试构建一个响应keyPress事件的UI。
我正在使用 Angular 和 RxJS 来检测事件。 [软件包是最新的]
代码类似于
this.keyboard$ = Observable.fromEvent(document, 'keypress')
.pipe(debounceTime(300))
.subscribe(e => {console.log(e);})
此代码在正常情况下可以正常工作,但是在极端情况下,当用户按下键的时间过长时,一旦释放键,就会记录第二次按下事件。
我找到了一种解决方法,但是按键功能使失败。
this.keyboard$ = Observable.fromEvent(document, 'keyup')
.pipe(debounceTime(300))
.subscribe(e => {console.log(e);})
我需要在每次按键检测一个事件。
任何人都可以指出代码段出了什么问题吗?预先感谢。
答案 0 :(得分:1)
我不熟悉Angular,但我认为它看起来像这样:
有一个变量,该变量保存最近按下的键的键控代码,另一个变量将确定事件是否会导致您的函数被调用。每次按下一个键都会调用您的函数,然后在听到带有正确代码的keyup事件之前,不允许再次调用该函数
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;
})
答案 1 :(得分:1)
实际上,这不是错误。 按住某个键时,浏览器会重新发送同一事件。其称为密钥重复。
参考:https://developer.mozilla.org/en-US/docs/Web/Events/keypress
为避免按键重复,您可以使用“ repeat”属性过滤重复的事件。
const { fromEvent} = rxjs;
const {filter, map} = rxjs.operators;
var keyboard$ = fromEvent(document, 'keydown')
.pipe(filter(event => !event.repeat))
.subscribe(event => {
console.log(event.code);
})
我在这里创建了一个JSFiddle,因此您可以自己尝试: https://jsfiddle.net/williamxsp/Lq9go1bt/