RxJs:拖放示例:添加 mousedragstart [英] RxJs: Drag and Drop example : add mousedragstart

查看:24
本文介绍了RxJs:拖放示例:添加 mousedragstart的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何使用 mousedragstart Observable="nofollow">拖放 RxJs 的示例.

How to implement a mousedragstart Observable using the Drag and Drop RxJs's example.

mousedragstart 应该在 mousedown 之后的第一个 mousedrag 之前发出,直到 mouseup.

mousedragstart should be emit before the first mousedrag after a mousedown until the mouseup.

我认为我们必须使用 flatMap/take(1)/takeUntil(mouseup) 但我每次都失败了..

I think we have to play with flatMap/take(1)/takeUntil(mouseup) but I fail every time..

更新

这里的困难不是避免 mousedragmousedragstart

Difficulty here is not avoid mousedrag to be emitted before mousedragstart

推荐答案

基于我之前的未解决根本问题的答案以及您提供的信息,我们在概念上定义了如下内容:

Building on my previous, not-addressing-the-root-problem answer, and the information you've provided, we conceptually have things defined as follows:

var dragTarget = document.getElementById('dragTarget');

var mouseup   = Rx.Observable.fromEvent(document,   'mouseup');
var mousemove = Rx.Observable.fromEvent(document,   'mousemove');
var mousedown = Rx.Observable.fromEvent(dragTarget, 'mousedown');

var dragstart = mousedown.flatMap(() =>
  mousemove
   .where(x => x.movementX !== 0 || x.movementY !== 0)
   .takeUntil(mouseup)
   .take(1)
);

var dragmove = mousedown.flatMap(() =>
  mousemove
    .where(x => x.movementX !== 0 || x.movementY !== 0)
    .takeUntil(mouseup)
);

这里的问题是事件之间的重叠;就与底层事件的关系而言,dragstart 由与第一个 dragmove 完全相同的事情触发.在这种情况下,订阅顺序将决定执行顺序,正如您所说,这不是您想要依赖的.为了解决这个问题,我们必须控制潜在的事件.

The problem here is the overlap between the events; in terms of relationship to the underlying events, dragstart is triggered by EXACTLY the same thing as the first dragmove. In this case, order of subscription will determine order of execution, which, as you've said, isn't something you want to rely on. To address this, we must take control of the underlying events.

这是一个简单的函数,它接受一个 observable 并返回一个包含两个 observable 的数组,这两个 observable 将发出与原始 observable 相同的值,但其中事件将始终在第二个 observable 之前传递给第一个 observable,无论哪个首先订阅:

Here's a simple function that takes an observable and returns an array containing two observables which will be issued the same values as the original observable but in which the events will always be passed to the first observable before the second observable, regardless of which is subscribed to first:

function prioritize(s$) {
  var first = new Rx.Subject();
  var second = s$.do(x => first.onNext(x)).share();

  return [
    Rx.Observable.using(
      () => second.subscribe(() => {}),
      () => first
    ),
    second
  ];
}

从那里,我们可以用这样的东西替换上面的适当部分:

From there, we can replace the appropriate parts above with something like this:

var mousedowns = prioritize(mousedown);

var dragstart = mousedowns[0].flatMap(() =>
 mousemove
   .where(x => x.movementX !== 0 || x.movementY !== 0)
   .takeUntil(mouseup)
   .take(1)
);

var dragmove = mousedowns[1].flatMap(() =>
  mousemove
    .where(x => x.movementX !== 0 || x.movementY !== 0)
    .takeUntil(mouseup)
);

dragmove.subscribe(() => console.log('dragmove'));
dragstart.subscribe(() => console.log('dragstart'));

这里是整个工作:

https://jsbin.com/qodilerofe/edit?js,console,output

这篇关于RxJs:拖放示例:添加 mousedragstart的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆