RxJs如何处理文档事件 [英] RxJs How do deal with document events
问题描述
开始使用RxJs。无法找到解决这个问题的方法。我有一个可拖动的控件:
Started using RxJs. Can't find a way around this problem. I have a draggable control:
startDrag = rx.Observable.fromEvent(myElem,'mousedown')
现在,因为控件太小 mousemove
和 mouseup
事件应该在文档级别(否则它不会停止拖动,除非光标正好在元素上)
now, because the control is too small mousemove
and mouseup
events should be at document level (otherwise it won't stop dragging unless cursor exactly on the element)
endDrag = rx.Observable.fromEvent document,'mouseup'
position = startDrag.flatMap ->
rx.Observable.fromEvent document,'mousemove'
.map (x)-> x.clientX
.takeUntil endDrag
现在我如何抓住正确的时刻没有被拖动( mouseup
)。
你看到订阅 endDrag
的问题?每次点击任何地方都会触发,而不仅仅是 myElem
如何一次检查所有3个属性?它应该只需要在 startDrag
和位置
now how do I "catch" the right moment when is not being dragged anymore (mouseup
).
you see the problem with subscribing to endDrag
? It will fire every time clicked anywhere, and not just myElem
How do I check all 3 properties at once? It should take only those document.mouseups that happened exactly after startDrag
and position
更新:我的意思是问题不在于移动元素。那部分很容易 - 订阅位置
,更改元素的css。
我的问题是 - 我需要检测 mouseup
的时刻,并知道被拖动的确切元素(页面上有多个元素)。怎么做我不知道。
Upd: I mean the problem is not with moving the element. That part is easy - subscribe to position
, change element's css.
My problem is - I need to detect the moment of mouseup
and know the exact element that's been dragged (there are multiple elements on the page). How to do that I have no idea.
推荐答案
我改编了拖放示例可以根据需要运行。
I have adapted the drag and drop example provided at the RxJS repo to behave as you need.
-
mouseUp
听文件
。
目标元素被添加到选择
。
拖动动作在 map
和 map
返回 mouseDown
事件中定位的元素。
Drag movements are handled inside of map
and map
returns the element that was targeted in the mouseDown
event.
致电 <$ c在 takeUntil(mouseUp)
之后$ c> last 所以 subscribe
只会拖动过程结束时(每次拖动一次)即可到达。
Call last
after takeUntil(mouseUp)
so subscribe
will only be reached when the drag process ends (once per drag).
function main() {
var dragTarget = document.getElementById('dragTarget');
// Get the three major events
var mouseup = Rx.Observable.fromEvent(document, 'mouseup');
var mousemove = Rx.Observable.fromEvent(document, 'mousemove');
var mousedown = Rx.Observable.fromEvent(dragTarget, 'mousedown');
var mousedrag = mousedown.selectMany(function(md) {
// calculate offsets when mouse down
var startX = md.offsetX;
var startY = md.offsetY;
// Calculate delta with mousemove until mouseup
return mousemove.select(function(mm) {
if (mm.preventDefault) mm.preventDefault();
else event.returnValue = false;
return {
// Include the targeted element
elem: mm.target,
pos: {
left: mm.clientX - startX,
top: mm.clientY - startY
}
};
})
.map(function(data) {
// Update position
dragTarget.style.top = data.pos.top + 'px';
dragTarget.style.left = data.pos.left + 'px';
// Just return the element
return data.elem;
})
.takeUntil(mouseup)
.last();
});
// Here we receive the element when the drag is finished
subscription = mousedrag.subscribe(function(elem) {
alert('Drag ended on #' + elem.id);
});
}
main();
#dragTarget {
position: absolute;
width: 20px;
height: 20px;
background: #0f0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/4.0.7/rx.all.min.js"></script>
<div id="dragTarget"></div>
这篇关于RxJs如何处理文档事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!