为什么RxJs在长按时记录2个事件?

时间:2019-03-31 23:26:28

标签: javascript angular rxjs

我正在尝试构建一个响应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);})

我需要在每次按键检测一个事件。

任何人都可以指出代码段出了什么问题吗?预先感谢。

2 个答案:

答案 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/