Javascript 取消按键拖动角度cdk拖放
我在一个应用程序中工作,从角材料CDK实现新的拖放,我试图取消按Esc键的元素拖动事件,我的意思是,我开始拖动元素,但如果我在拖动元素时按Esc键,它应该回到我开始拖动它的位置,到目前为止,我还没有找到一种方法来做到这一点,有人知道我如何做到这一点吗。cdk文档中没有关于这一点的任何想法。我试着做这样的事情 模板Javascript 取消按键拖动角度cdk拖放,javascript,angular,angular-material,angular-cdk,Javascript,Angular,Angular Material,Angular Cdk,我在一个应用程序中工作,从角材料CDK实现新的拖放,我试图取消按Esc键的元素拖动事件,我的意思是,我开始拖动元素,但如果我在拖动元素时按Esc键,它应该回到我开始拖动它的位置,到目前为止,我还没有找到一种方法来做到这一点,有人知道我如何做到这一点吗。cdk文档中没有关于这一点的任何想法。我试着做这样的事情 模板 <div cdkDropList class="example-list" (cdkDropListDropped)="drop($event)"> <div c
<div cdkDropList class="example-list" (cdkDropListDropped)="drop($event)">
<div class="example-box" *ngFor="let movie of movies" (cdkDragEnded)="onDragEnded($event)" cdkDrag>{{movie}}</div>
</div>
但是到目前为止还没有成功。您可以使用类似于
@HostListener('window:keyup', ['$event'])
handleKeyboardEvent(event: KeyboardEvent) {
if (event.code === 'Escape') {
// call dragend event
}
}
可以使用以下命令将拖动的项目移动到某个位置:
event['source']['element']['nativeElement']['style']['transform'] = 'translate3d(0,0,0)';
event['source']['_dragRef']['_activeTransform'] = {x: 0, y: 0};
event['source']['_dragRef']['_passiveTransform'] = {x: 0, y: 0};
我也长期面临这个问题。最后,我可以通过调度一个
mouseup
事件来修复它,该事件将充当用户释放鼠标的角色
@HostListener('window:keyup', ['$event'])
handleKeyboardEvent(event: KeyboardEvent) {
if (event.key === 'Escape') {
document.dispatchEvent(new Event('mouseup'));
}
}
这是一个非常粗糙的解决方案,它有缺点。事实上,您并不是在取消拖动,而是在拖放。这意味着,如果您悬停在cdkDropList
上或其中一个处于活动状态,它将触发该列表的cdkdroplistdroped
emmiter。您可以通过添加标志轻松解决此问题
private _canceledByEsq = false;
@HostListener('window:keyup', ['$event'])
handleKeyboardEvent(event: KeyboardEvent) {
if (event.key === 'Escape') {
this._canceledByEsq = true;
document.dispatchEvent(new Event('mouseup'));
}
}
handleDrop() {
if (!this._canceledByEsq) {
// Do my data manipulations
}
}
希望这能帮助你……:) 最好的方法是调用
event.source.\u dragRef.reset()按ESC
键时编码>(注释中提到@AleRubis)。
现在的问题是,在cdkDrag事件(ESC
key event)之外,从何处可以获得dragRef,当拖动开始时,可以将其保存在这样的组件变量中
组成部分:
cdkDragStarted=(事件)=>{
this.dragRef=event.source.\u dragRef;
}
模板:
拖拉段落
这是一个使用rxjs的版本。它需要引用CdkDrag
作为ViewChild。不幸的是,由于没有公共方法停止在DragRef
上拖动,因此必须使用dispatchEvent
作为结束拖动过程的唯一方法
下面的示例中有两个部分。发生的情况是,结束事件只能在开始后收听,而该收听实例可以由按escape触发的主题停止
- 在AfterViewInit中,从
CdkDrag
指令创建对已启动的事件发射器的订阅
- 启动事件后,切换到侦听的流结束
- 如果触发取消请求,则流将由
takeUntil
操作符结束,指令将调用reset()
重置位置,并使用dispatchEvent()
停止拖动过程
- 否则,一旦触发end事件,就会从OP调用
ondragend()
方法
- 除非有一些真正有趣的事情发生,否则end事件每次启动最多只会触发一次,因此不需要额外的
take(1)
好的,我可以检查是否按下了键,但是我如何重置拖动到原始位置的元素并取消拖动。您可以在拖动开始事件时记住变量中的x和y位置,这不是特定的,问题是如何在拖动开始后取消拖动事件,并在按键时触发鼠标。在拖动带有任何事件的此类元素时,您可以获得其实际位置,并在取消时使用此位置。。如果您为问题创建stackbiz,这将非常有用。确定问题是如何取消拖动事件,而不是如何将拖动的元素返回到原始位置,仅取消拖动事件元素返回原始位置而不记住x或y位置,所以问题是如何取消元素的拖动,从拖动开始。你解决了吗?感谢,E.不幸的是,还没有…将拖动的元素重置为其原点,而不是手动设置元素转换和源。_被动转换
现在可以执行事件.source。_dragRef.reset()代码>对我不起作用。reset()似乎什么也不做(使用Angular 9.1.X测试)。因此,我更喜欢@danizep的解决方案。
private _canceledByEsq = false;
@HostListener('window:keyup', ['$event'])
handleKeyboardEvent(event: KeyboardEvent) {
if (event.key === 'Escape') {
this._canceledByEsq = true;
document.dispatchEvent(new Event('mouseup'));
}
}
handleDrop() {
if (!this._canceledByEsq) {
// Do my data manipulations
}
}
private dragCancelRequest = new Subject();
ngAfterViewInit() {
this.drag.started.pipe(
switchMap(({ source }) => source.ended.pipe(
takeUntil(this.dragCancelRequest.pipe(tap(() => {
source.reset();
document.dispatchEvent(new Event('mouseup'));
})))
)),
tap(x => this.onDragEnded(x))
).subscribe();
}
@HostListener('window:keyup', ['$event'])
handleKeyboardEvent(event: KeyboardEvent) {
if (event.key === 'Escape') {
this.dragCancelRequest.next();
}
}