带条件的RxJs mousemove事件

时间:2018-09-26 06:33:28

标签: javascript javascript-events rxjs

我正在为此苦苦挣扎,而且我不知道如何进行。我只想在用户停止使用mousemove并且在特定元素内时捕获鼠标事件。

const { fromEvent } = rxjs;
const { debounceTime, tap, filter } = rxjs.operators;

const square = document.querySelectorAll("#square");

let isCursorOverSquare = true;

const move$ = fromEvent(square, "mousemove");
const enter$ = fromEvent(square, "mouseenter");
const leave$ = fromEvent(square, "mouseleave");

enter$.pipe(
    tap(() => isCursorOverSquare = true)
).subscribe();

leave$.pipe(
    tap(() => isCursorOverSquare = false)
).subscribe();

move$
.pipe(
    debounceTime(2000),
    filter(() => isCursorOverSquare)
)
.subscribe(
   (e) => {
       console.log(e.target); 
});
#square {
  width: 200px;
  height: 200px;
  display: block;
  border: 1px solid black;
}
<script src="https://unpkg.com/rxjs@6.3.2/bundles/rxjs.umd.min.js"></script>
<div id="square"></div>

我不知道的是,如果用户从正方形移动到外部(例如,当用户将光标放在正方形内时,仅处理逻辑),如何跳过console.log

>

编辑: 我设法解决了这个问题,但这不是“ RxJs”方法。现在,将isCursorOverSquare变量设置为truefalse,然后使用filter运算符。有没有更“被动”的方式来解决这个问题?

2 个答案:

答案 0 :(得分:2)

因此,如果我正确理解了您的问题,您想:

  • 跟踪所有鼠标移动(mousemove事件流-fromevent
  • 运动停止一定时间(debounce
  • 验证它是否在边界框中(filter

因此,根据性能的不同,您可以始终使用.switchMap()运算符输入事件,或者始终启动鼠标移动事件或仅在启动正方形后才启动mousemove事件:

enter$
  .switchMap(_ => $moves
    .debounceTime(2000)
    .takeUntil(leave$)
  )
  .subscribe(finalMouseMoveEventInSquare => {});

答案 1 :(得分:0)

您遇到的问题是,当光标仍然位于正方形中时,会触发最后一个mousemove事件,但是防抖动会延迟可观察到的时间,直到光标离开正方形为止。您可以通过仅观察到鼠标离开正方形即可解决此问题。这是此答案的完整code

<head>
    <style>
        #square {
            width: 200px;
            height: 200px;
            display: block;
            border: 1px solid black;
        }
    </style>
</head>

<body>
    <div id="square"></div>
    <script src="https://unpkg.com/rxjs@6.3.2/bundles/rxjs.umd.min.js"></script>
    <script>
        const { fromEvent } = rxjs;
        const { debounceTime, repeat , takeUntil } = rxjs.operators;

        const square = document.getElementById("square");

        const move$ = fromEvent(square, "mousemove").pipe(debounceTime(2000));
        const enter$ = fromEvent(square, "mouseenter");
        const leave$ = fromEvent(square, "mouseleave");

        move$.pipe(takeUntil(leave$), repeat()).subscribe((e) => console.log(e.target));
    </script>
</body>

repeat运算符是必需的,否则,一旦鼠标第一次离开正方形,当鼠标下一次进入正方形时,将不会重复观察到的内容。如果您的预期行为是在鼠标第一次离开正方形后可观察到的停止发光,请随时删除重复操作符。希望这对您有所帮助,如果您有任何疑问,请告诉我!