Я борюсь с этим и не знаю, что делать дальше. Я хочу захватить событие мыши только тогда, когда пользователь останавливается с 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, если пользователь переходит от квадрата к внешнему (т.е. обрабатывает только логику, когда пользователь находится с курсором внутри квадрата).

< Сильный > EDIT : У меня получилось поработать, но это не способ "RxJs". Теперь я устанавливаю для переменной isCursorOverSquare значения true и false, а затем использую оператор filter. Есть ли более «лучший» способ справиться с этим?

0
Gabriel 26 Сен 2018 в 09:33

2 ответа

Лучший ответ

Итак, если я правильно понимаю ваш вопрос, вы хотите:

Таким образом, в зависимости от производительности вы можете либо всегда обрабатывать события mousemove, либо запускать события mousemove только после входа в квадрат, используя .switchMap() оператор:

enter$
  .switchMap(_ => $moves
    .debounceTime(2000)
    .takeUntil(leave$)
  )
  .subscribe(finalMouseMoveEventInSquare => {});
2
Mark van Straten 26 Сен 2018 в 07:58

Проблема, которая у вас есть, заключается в том, что последнее событие mousemove запускается, когда курсор все еще находится в квадрате, но противодействие задерживает наблюдаемое до тех пор, пока курсор не покинет квадрат. Вы можете решить эту проблему, беря наблюдаемое только до тех пор, пока мышь не покинет квадрат. Вот полный код для этого ответа:

<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 необходим, так как в противном случае, когда мышь покинет квадрат в первый раз наблюдаемое не будет повторяться, когда мышь в следующий раз войдет в квадрат. Если ваше предполагаемое поведение состоит в том, чтобы наблюдаемое перестало излучать после того, как мышь покинула квадрат в первый раз, не стесняйтесь удалить оператор повторения. Надеюсь, это поможет вам, дайте мне знать, если у вас возникнут вопросы!

0
tnc1997 26 Сен 2018 в 08:14