@@ -16,6 +16,7 @@ export interface DDDraggableOpt {
16
16
handle ?: string ;
17
17
helper ?: 'clone' | HTMLElement | ( ( event : Event ) => HTMLElement ) ;
18
18
cancel ?: string ;
19
+ dragElement ?: string | HTMLElement ;
19
20
// containment?: string | HTMLElement; // TODO: not implemented yet
20
21
// revert?: string | boolean | unknown; // TODO: not implemented yet
21
22
// scroll?: boolean;
@@ -58,8 +59,6 @@ export class DDDraggable extends DDBaseImplement implements HTMLElementExtendOpt
58
59
protected dragScale : DragScaleReciprocal = { x : 1 , y : 1 } ;
59
60
/** @internal */
60
61
protected dragElementOriginStyle : Array < string > ;
61
- /** @internal */
62
- protected dragEl : HTMLElement ;
63
62
/** @internal true while we are dragging an item around */
64
63
protected dragging : boolean ;
65
64
/** @internal */
@@ -76,16 +75,23 @@ export class DDDraggable extends DDBaseImplement implements HTMLElementExtendOpt
76
75
this . el = el ;
77
76
this . option = option ;
78
77
79
- // get the element that is actually supposed to be dragged by
80
- let handleName = option . handle . substring ( 1 ) ;
81
- this . dragEl = el . classList . contains ( handleName ) ? el : el . querySelector ( option . handle ) || el ;
82
78
// create var event binding so we can easily remove and still look like TS methods (unlike anonymous functions)
83
79
this . _mouseDown = this . _mouseDown . bind ( this ) ;
84
80
this . _mouseMove = this . _mouseMove . bind ( this ) ;
85
81
this . _mouseUp = this . _mouseUp . bind ( this ) ;
86
82
this . enable ( ) ;
87
83
}
88
84
85
+ /** @internal */
86
+ protected get dragElement ( ) {
87
+ let handleName = this . option . handle . substring ( 1 ) ;
88
+ let dragEl = this . el . classList . contains ( handleName ) ? this . el : this . el . querySelector ( this . option . handle ) || this . el ;
89
+ if ( this . option . dragElement ) {
90
+ dragEl = this . option . dragElement instanceof HTMLElement ? this . option . dragElement : ( document . querySelector ( this . option . dragElement ) ?? dragEl ) ;
91
+ }
92
+ return dragEl ;
93
+ }
94
+
89
95
public on ( event : DDDragEvent , callback : ( event : DragEvent ) => void ) : void {
90
96
super . on ( event , callback ) ;
91
97
}
@@ -97,10 +103,10 @@ export class DDDraggable extends DDBaseImplement implements HTMLElementExtendOpt
97
103
public enable ( ) : void {
98
104
if ( this . disabled === false ) return ;
99
105
super . enable ( ) ;
100
- this . dragEl . addEventListener ( 'mousedown' , this . _mouseDown ) ;
106
+ document . addEventListener ( 'mousedown' , this . _mouseDown ) ;
101
107
if ( isTouch ) {
102
- this . dragEl . addEventListener ( 'touchstart' , touchstart ) ;
103
- this . dragEl . addEventListener ( 'pointerdown' , pointerdown ) ;
108
+ document . addEventListener ( 'touchstart' , touchstart ) ;
109
+ document . addEventListener ( 'pointerdown' , pointerdown ) ;
104
110
// this.dragEl.style.touchAction = 'none'; // not needed unlike pointerdown doc comment
105
111
}
106
112
this . el . classList . remove ( 'ui-draggable-disabled' ) ;
@@ -109,10 +115,10 @@ export class DDDraggable extends DDBaseImplement implements HTMLElementExtendOpt
109
115
public disable ( forDestroy = false ) : void {
110
116
if ( this . disabled === true ) return ;
111
117
super . disable ( ) ;
112
- this . dragEl . removeEventListener ( 'mousedown' , this . _mouseDown ) ;
118
+ document . removeEventListener ( 'mousedown' , this . _mouseDown ) ;
113
119
if ( isTouch ) {
114
- this . dragEl . removeEventListener ( 'touchstart' , touchstart ) ;
115
- this . dragEl . removeEventListener ( 'pointerdown' , pointerdown ) ;
120
+ document . removeEventListener ( 'touchstart' , touchstart ) ;
121
+ document . removeEventListener ( 'pointerdown' , pointerdown ) ;
116
122
}
117
123
if ( ! forDestroy ) this . el . classList . add ( 'ui-draggable-disabled' ) ;
118
124
}
@@ -139,6 +145,10 @@ export class DDDraggable extends DDBaseImplement implements HTMLElementExtendOpt
139
145
if ( DDManager . mouseHandled ) return ;
140
146
if ( e . button !== 0 ) return true ; // only left click
141
147
148
+ if ( e . target !== this . dragElement && ! this . dragElement . contains ( e . target as HTMLElement ) ) {
149
+ return ;
150
+ }
151
+
142
152
// make sure we are not clicking on known object that handles mouseDown, or ones supplied by the user
143
153
if ( ( e . target as HTMLElement ) . closest ( skipMouseDown ) ) return true ;
144
154
if ( this . option . cancel ) {
@@ -161,8 +171,8 @@ export class DDDraggable extends DDBaseImplement implements HTMLElementExtendOpt
161
171
document . addEventListener ( 'mousemove' , this . _mouseMove , true ) ; // true=capture, not bubble
162
172
document . addEventListener ( 'mouseup' , this . _mouseUp , true ) ;
163
173
if ( isTouch ) {
164
- this . dragEl . addEventListener ( 'touchmove' , touchmove ) ;
165
- this . dragEl . addEventListener ( 'touchend' , touchend ) ;
174
+ this . dragElement . addEventListener ( 'touchmove' , touchmove ) ;
175
+ this . dragElement . addEventListener ( 'touchend' , touchend ) ;
166
176
}
167
177
168
178
e . preventDefault ( ) ;
@@ -232,8 +242,8 @@ export class DDDraggable extends DDBaseImplement implements HTMLElementExtendOpt
232
242
document . removeEventListener ( 'mousemove' , this . _mouseMove , true ) ;
233
243
document . removeEventListener ( 'mouseup' , this . _mouseUp , true ) ;
234
244
if ( isTouch ) {
235
- this . dragEl . removeEventListener ( 'touchmove' , touchmove , true ) ;
236
- this . dragEl . removeEventListener ( 'touchend' , touchend , true ) ;
245
+ this . dragElement . removeEventListener ( 'touchmove' , touchmove , true ) ;
246
+ this . dragElement . removeEventListener ( 'touchend' , touchend , true ) ;
237
247
}
238
248
if ( this . dragging ) {
239
249
delete this . dragging ;
0 commit comments