使用 RXjs 拖放

bjo*_*lom 1 drag-and-drop rxjs

我正在为 RXJS 的拖放行为而苦苦挣扎。我想在 250 毫秒鼠标按下后开始拖动元素,以免劫持该元素上的点击事件。

到目前为止,开始拖动有效,但停止拖动从未被调用。有谁知道为什么?

let button = document.querySelector('.button');

let mouseDownStream = Rx.Observable.fromEvent(button, 'mousedown');
let mouseUpStream = Rx.Observable.fromEvent(button, 'mouseup');

let dragStream = mouseDownStream
  .flatMap((event) => {
    return Rx.Observable
      .return(event)
      .delay(250)
      .takeUntil(mouseUpStream)
  });

let dropStream = mouseUpStream
  .flatMap((event) => {
    return Rx.Observable
      .return(event)
      .skipUntil(dragStream)
  });

dragStream.subscribe(event => console.log('start drag'));
dropStream.subscribe(event => console.log('stop drag'));
Run Code Online (Sandbox Code Playgroud)

JSBin

ols*_*lsn 5

我已经更新了您的代码示例以使其运行,我做了什么:

  • flatMaps 与switchMaps (switchMap是 的别名flatMapLatest)交换这将确保它只接受最新的事件,如果发出新事件,它将取消任何旧的子事件 => 在这种情况下flatMap可能工作正常,但更安全使用switchMap,也是一个经验法则:如有疑问:使用switchMap
  • dropStream基于/dragStream现在发起
  • 删除了skipUntil,这是一个赛车条件问题,因为它会在一些 mouseUp 之后的下一次 dragStream-emission 之后首先触发(这将需要及时返回)
  • 将 mouseUp-target 从buttonto交换document(更方便的是,对于 while 的工作并不是很重要)

let button = document.querySelector('.button');

let mouseDownStream = Rx.Observable.fromEvent(button, 'mousedown');
let mouseUpStream = Rx.Observable.fromEvent(document, 'mouseup');

let dragStream = mouseDownStream
  .switchMap((event) => {
    return Rx.Observable
      .return(event)
      .delay(250)
      .takeUntil(mouseUpStream)
  });

let dropStream = dragStream
  .switchMap(() => mouseUpStream.take(1))

dragStream.subscribe(event => console.log('start drag'));
dropStream.subscribe(event => console.log('stop drag'));
Run Code Online (Sandbox Code Playgroud)
<!DOCTYPE html>
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/4.1.0/rx.all.js"></script>
  <meta charset="utf-8">
  <title>JS Bin</title>
</head>
<body>
<button class="button">Button</button>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)