如何使用 Drag and Drop RxJs's example 实现 mousedragstart
Observable .
mousedragstart
应该在 mousedown
之后的第一个 mousedrag
之前发出,直到 mouseup
。
我认为我们必须使用 flatMap
/take(1)
/takeUntil(mouseup)
但我每次都失败..
更新
这里的难点不是避免 mousedrag
在 mousedragstart
之前发射
最佳答案
基于我之前的非解决根本问题的回答以及您提供的信息,我们在概念上定义如下:
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 完全相同。在这种情况下,订阅顺序将决定执行顺序,正如您所说,这不是您想要依赖的。为了解决这个问题,我们必须控制底层事件。
这是一个简单的函数,它接受一个 observable 并返回一个包含两个 observable 的数组,这两个 observable 将被发出与原始 observable 相同的值,但其中事件将始终在第二个 observable 之前传递给第一个 observable,无论哪个首先订阅:
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
];
}
从那里,我们可以用这样的东西替换上面的适当部分:
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'));
这是整个工作过程:
关于javascript - RxJs:拖放示例:添加 mousedragstart,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35950593/