如何使用Rx在Angular 2中实现可拖动div
我一直在尝试使用Angular 2制作一个可拖动的div。我将使用作为起点,只是真正地调整代码以考虑删除如何使用Rx在Angular 2中实现可拖动div,angular,angular2-directives,rxjs5,Angular,Angular2 Directives,Rxjs5,我一直在尝试使用Angular 2制作一个可拖动的div。我将使用作为起点,只是真正地调整代码以考虑删除toRx()方法。代码可以工作,但它不考虑mouseout事件。这意味着,如果我单击一个可拖动的div,并缓慢移动鼠标,该div将随鼠标移动。但是,如果我移动鼠标太快,则会发送一个mouseout事件,而不是mousemove事件,并停止拖动 鼠标移动到触发mouseout事件后,如何保持拖动?我已经尝试将mouseout事件流与mousemove事件流合并,这样mouseout事件就像mou
toRx()
方法。代码可以工作,但它不考虑mouseout
事件。这意味着,如果我单击一个可拖动的div,并缓慢移动鼠标,该div将随鼠标移动。但是,如果我移动鼠标太快,则会发送一个mouseout
事件,而不是mousemove
事件,并停止拖动
鼠标移动到触发mouseout
事件后,如何保持拖动?我已经尝试将mouseout
事件流与mousemove
事件流合并,这样mouseout
事件就像mousemove
事件一样处理,但这不起作用
我使用的是Angular 2.0.0-beta.12
从'angular2/core'导入{Component,Directive,HostListener,EventEmitter,ElementRef,OnInit};
从'rxjs/Rx'导入{map,merge};
@指示({
选择器:“[Dragable]”
})
导出类可拖动的实现OnInit{
mouseup=neweventemitter();
mousedown=neweventemitter();
mousemove=neweventemitter();
mouseout=neweventemitter();
@HostListener('mouseup',['$event']))
onMouseup(事件){
this.mouseup.emit(事件);
}
@HostListener('mousedown',['$event']))
onMousedown(事件){
this.mousedown.emit(事件);
return false;//对事件调用preventDefault()
}
@HostListener('mousemove',['$event']))
onMousemove(事件){
this.mousemove.emit(事件);
}
@HostListener('mouseout',['$event']))
onMouseout(事件){
this.mouseout.emit(事件);
return false;//对事件调用preventDefault()
}
构造函数(公共元素:ElementRef){
this.element.nativeElement.style.position='relative';
this.element.nativeElement.style.cursor='pointer';
地图;
合并
this.mousedrag=this.mousedown.map(事件=>{
返回{
top:event.clientY-this.element.nativeElement.getBoundingClientRect().top
左:event.clientX-this.element.nativeElement.getBoundingClientRect().left,
};
})
.平面图(
imageOffset=>this.mousemove.merge(this.mouseout.map)(pos=>({
顶部:pos.clientY-imageOffset.top,
左:pos.clientX-imageOffset.left
}))
.takeUntil(这个.mouseup)
);
}
恩戈尼尼特(){
这是mousedrag.subscribe({
下一步:pos=>{
this.element.nativeElement.style.top=pos.top+'px';
this.element.nativeElement.style.left=pos.left+'px';
}
});
}
}
@组成部分({
选择器:“我的应用程序”,
模板:`
你好,世界!
`,
指令:[可拖动,],
})
导出类AppComponent{
}
您可以创建一个覆盖屏幕不动产的大div。首先,该div的z索引低于要拖动的div。在接收mousedown时,您将div的z索引更改为高于drag元素,并在此div上接收鼠标移动事件。您可以使用它来计算drag元素的位置。然后,当您收到鼠标时,可以停止并再次发送div
我最近用Angular2编写了一个模块化拖放框架。请尝试一下并提供反馈
但是,一旦mouseout事件被触发,我就会停止拖动。我在中找到了这个问题的答案。问题的关键在于,鼠标事件仅在鼠标位于某个元素上时才会发送到该元素。因此,我们确实希望
mousedown
事件仅限于特定元素,但我们必须跟踪全局mousemove
和mouseup
事件。这是新代码。请注意,在onMouseup
和onMousemove
上使用@HostListener
装饰器将目标指定为document:mouseup
和document:mousemove
。这就是全局事件通过管道传输到Rx流的方式
没有提到这个target:eventName
语法,但是提到了它。它似乎在2.0.0-beta.12版本中仍然有效
@指令({
选择器:“[Dragable]”
})
导出类可拖动的实现OnInit{
mouseup=neweventemitter();
mousedown=neweventemitter();
mousemove=neweventemitter();
鼠背袋:可见;
@HostListener('文档:mouseup',['$event']))
onMouseup(事件:MouseEvent){
this.mouseup.emit(事件);
}
@HostListener('mousedown',['$event']))
onMousedown(事件:MouseEvent){
this.mousedown.emit(事件);
return false;//对事件调用preventDefault()
}
@HostListener('文档:mousemove',['$event']))
onMousemove(事件:MouseEvent){
this.mousemove.emit(事件);
}
构造函数(公共元素:ElementRef){
this.element.nativeElement.style.position='relative';
this.element.nativeElement.style.cursor='pointer';
this.mousedrag=this.mousedown.map(事件=>{
返回{
top:event.clientY-this.element.nativeElement.getBoundingClientRect().top
左:event.clientX-this.element.nativeElement.getBoundingClientRect().left,
};
})
.平面图(
imageOffset=>this.mousemove.map(pos=>({
顶部:pos.clientY-imageOffset.top,
左:pos.clientX-imageOffset.left
}))
.takeUntil(这个.mouseup)
);
}
恩戈尼尼特(){
这是mousedrag.subscribe({
下一步:pos=>{
this.element.nativeElement.style.top=pos.top+'px';
this.element.nativeElement.style.left=pos.left+'px
@Directive({
selector: '[ng2-draggable]'
})
export class Draggable implements OnInit{
topStart:number=0;
leftStart:number=0;
_allowDrag:boolean = true;
md:boolean;
constructor(public element: ElementRef) {}
ngOnInit(){
// css changes
if(this._allowDrag){
this.element.nativeElement.style.position = 'relative';
this.element.nativeElement.className += ' cursor-draggable';
}
}
@HostListener('mousedown', ['$event'])
onMouseDown(event:MouseEvent) {
if(event.button === 2)
return; // prevents right click drag, remove his if you don't want it
this.md = true;
this.topStart = event.clientY - this.element.nativeElement.style.top.replace('px','');
this.leftStart = event.clientX - this.element.nativeElement.style.left.replace('px','');
}
@HostListener('document:mouseup')
onMouseUp(event:MouseEvent) {
this.md = false;
}
@HostListener('document:mousemove', ['$event'])
onMouseMove(event:MouseEvent) {
if(this.md && this._allowDrag){
this.element.nativeElement.style.top = (event.clientY - this.topStart) + 'px';
this.element.nativeElement.style.left = (event.clientX - this.leftStart) + 'px';
}
}
@HostListener('touchstart', ['$event'])
onTouchStart(event:TouchEvent) {
this.md = true;
this.topStart = event.changedTouches[0].clientY - this.element.nativeElement.style.top.replace('px','');
this.leftStart = event.changedTouches[0].clientX - this.element.nativeElement.style.left.replace('px','');
event.stopPropagation();
}
@HostListener('document:touchend')
onTouchEnd() {
this.md = false;
}
@HostListener('document:touchmove', ['$event'])
onTouchMove(event:TouchEvent) {
if(this.md && this._allowDrag){
this.element.nativeElement.style.top = ( event.changedTouches[0].clientY - this.topStart ) + 'px';
this.element.nativeElement.style.left = ( event.changedTouches[0].clientX - this.leftStart ) + 'px';
}
event.stopPropagation();
}
@Input('ng2-draggable')
set allowDrag(value:boolean){
this._allowDrag = value;
if(this._allowDrag)
this.element.nativeElement.className += ' cursor-draggable';
else
this.element.nativeElement.className = this.element.nativeElement.className
.replace(' cursor-draggable','');
}
}
<div class="popup-win" (mousedown)="mousedown($event)"></div>
constructor(private elementRef: ElementRef,
private renderer: Renderer2) {}
mousedown(event: any) {
this.xStartElementPoint = this.curX;
this.yStartElementPoint = this.curY;
this.xStartMousePoint = event.pageX;
this.yStartMousePoint = event.pageY;
this.mousemoveEvent = this.renderer.listen("document", "mousemove", this.dragging);
this.mouseupEvent = this.renderer.listen("document", "mouseup", this.mouseup);
}
dragging(event: any) {
this.curX = this.xStartElementPoint + (event.pageX - this.xStartMousePoint);
this.curY = this.yStartElementPoint + (event.pageY - this.yStartMousePoint);
}
mouseup(event: any) {
// Remove listeners
this.mousemoveEvent();
this.mouseupEvent();
}