1
1
import { Component } from "./component" ;
2
- import $ from "cash-dom" ;
3
2
import { M } from "./global" ;
3
+ import $ from "cash-dom" ;
4
4
5
5
let _defaults = {
6
6
onOpen : undefined ,
7
7
onClose : undefined
8
8
} ;
9
9
10
- /**
11
- * @class
12
- *
13
- */
14
10
export class TapTarget extends Component {
15
- isOpen : any ;
11
+ isOpen : boolean ;
16
12
wrapper : any ;
17
13
private _handleDocumentClickBound : ( this : HTMLElement , ev : MouseEvent ) => any ;
18
- $origin : any ;
14
+ _origin : HTMLElement ;
19
15
private _handleTargetClickBound : EventListenerOrEventListenerObject ;
20
16
originEl : any ;
21
17
private _handleOriginClickBound : any ;
22
18
private _handleThrottledResizeBound : any ;
23
19
waveEl : HTMLElement & Element & Node ;
24
20
contentEl : any ;
25
- /**
26
- * Construct TapTarget instance
27
- * @constructor
28
- * @param {Element } el
29
- * @param {Object } options
30
- */
21
+
31
22
constructor ( el , options ) {
32
23
super ( TapTarget , el , options ) ;
33
-
34
24
( this . el as any ) . M_TapTarget = this ;
35
-
36
- /**
37
- * Options for the select
38
- * @member TapTarget#options
39
- * @prop {Function } onOpen - Callback function called when feature discovery is opened
40
- * @prop {Function } onClose - Callback function called when feature discovery is closed
41
- */
42
- this . options = $ . extend ( { } , TapTarget . defaults , options ) ;
43
-
25
+ this . options = { ...TapTarget . defaults , ...options } ;
44
26
this . isOpen = false ;
45
-
46
27
// setup
47
- this . $origin = $ ( '#' + this . $el . attr ( 'data-target' ) ) ;
28
+ this . _origin = document . querySelector ( '#' + this . el . getAttribute ( 'data-target' ) ) ;
29
+ // $('#' + this.$el.attr('data-target'));
48
30
this . _setup ( ) ;
49
-
50
31
this . _calculatePositioning ( ) ;
51
32
this . _setupEventHandlers ( ) ;
52
33
}
@@ -59,155 +40,121 @@ import { M } from "./global";
59
40
return super . init ( this , els , options ) ;
60
41
}
61
42
62
- /**
63
- * Get Instance
64
- */
65
43
static getInstance ( el ) {
66
44
let domElem = ! ! el . jquery ? el [ 0 ] : el ;
67
45
return domElem . M_TapTarget ;
68
46
}
69
47
70
- /**
71
- * Teardown component
72
- */
73
48
destroy ( ) {
74
49
this . _removeEventHandlers ( ) ;
75
50
( this . el as any ) . TapTarget = undefined ;
76
51
}
77
52
78
- /**
79
- * Setup Event Handlers
80
- */
81
53
_setupEventHandlers ( ) {
82
54
this . _handleDocumentClickBound = this . _handleDocumentClick . bind ( this ) ;
83
55
this . _handleTargetClickBound = this . _handleTargetClick . bind ( this ) ;
84
56
this . _handleOriginClickBound = this . _handleOriginClick . bind ( this ) ;
85
-
86
57
this . el . addEventListener ( 'click' , this . _handleTargetClickBound ) ;
87
58
this . originEl . addEventListener ( 'click' , this . _handleOriginClickBound ) ;
88
-
89
59
// Resize
90
60
let throttledResize = M . throttle ( this . _handleResize , 200 ) ;
91
61
this . _handleThrottledResizeBound = throttledResize . bind ( this ) ;
92
-
93
62
window . addEventListener ( 'resize' , this . _handleThrottledResizeBound ) ;
94
63
}
95
64
96
- /**
97
- * Remove Event Handlers
98
- */
99
65
_removeEventHandlers ( ) {
100
66
this . el . removeEventListener ( 'click' , this . _handleTargetClickBound ) ;
101
67
this . originEl . removeEventListener ( 'click' , this . _handleOriginClickBound ) ;
102
68
window . removeEventListener ( 'resize' , this . _handleThrottledResizeBound ) ;
103
69
}
104
70
105
- /**
106
- * Handle Target Click
107
- * @param {Event } e
108
- */
109
71
_handleTargetClick ( e ) {
110
72
this . open ( ) ;
111
73
}
112
74
113
- /**
114
- * Handle Origin Click
115
- * @param {Event } e
116
- */
117
75
_handleOriginClick ( e ) {
118
76
this . close ( ) ;
119
77
}
120
78
121
- /**
122
- * Handle Resize
123
- * @param {Event } e
124
- */
125
79
_handleResize ( e ) {
126
80
this . _calculatePositioning ( ) ;
127
81
}
128
82
129
- /**
130
- * Handle Resize
131
- * @param {Event } e
132
- */
133
83
_handleDocumentClick ( e ) {
134
- if ( ! $ ( e . target ) . closest ( '.tap-target-wrapper' ) . length ) {
84
+ if ( ! e . target . closest ( '.tap-target-wrapper' ) ) {
135
85
this . close ( ) ;
136
86
e . preventDefault ( ) ;
137
87
e . stopPropagation ( ) ;
138
88
}
139
89
}
140
90
141
- /**
142
- * Setup Tap Target
143
- */
144
91
_setup ( ) {
145
92
// Creating tap target
146
93
this . wrapper = this . $el . parent ( ) [ 0 ] ;
147
94
this . waveEl = $ ( this . wrapper ) . find ( '.tap-target-wave' ) [ 0 ] ;
148
95
this . originEl = $ ( this . wrapper ) . find ( '.tap-target-origin' ) [ 0 ] ;
149
96
this . contentEl = this . $el . find ( '.tap-target-content' ) [ 0 ] ;
150
-
151
97
// Creating wrapper
152
98
if ( ! $ ( this . wrapper ) . hasClass ( '.tap-target-wrapper' ) ) {
153
99
this . wrapper = document . createElement ( 'div' ) ;
154
100
this . wrapper . classList . add ( 'tap-target-wrapper' ) ;
155
101
this . $el . before ( $ ( this . wrapper ) ) ;
156
102
this . wrapper . append ( this . el ) ;
157
103
}
158
-
159
104
// Creating content
160
105
if ( ! this . contentEl ) {
161
106
this . contentEl = document . createElement ( 'div' ) ;
162
107
this . contentEl . classList . add ( 'tap-target-content' ) ;
163
108
this . $el . append ( this . contentEl ) ;
164
109
}
165
-
166
110
// Creating foreground wave
167
111
if ( ! this . waveEl ) {
168
112
this . waveEl = document . createElement ( 'div' ) ;
169
113
this . waveEl . classList . add ( 'tap-target-wave' ) ;
170
-
171
114
// Creating origin
172
115
if ( ! this . originEl ) {
173
- this . originEl = this . $origin . clone ( true , true ) ;
174
- this . originEl . addClass ( 'tap-target-origin' ) ;
175
- this . originEl . removeAttr ( 'id' ) ;
176
- this . originEl . removeAttr ( 'style' ) ;
177
- this . originEl = this . originEl [ 0 ] ;
116
+ this . originEl = this . _origin . cloneNode ( true ) ; // .clone(true, true);
117
+ this . originEl . classList . add ( 'tap-target-origin' ) ;
118
+ this . originEl . removeAttribute ( 'id' ) ;
119
+ this . originEl . removeAttribute ( 'style' ) ;
120
+ // this.originEl = this.originEl;
178
121
this . waveEl . append ( this . originEl ) ;
179
122
}
180
-
181
123
this . wrapper . append ( this . waveEl ) ;
182
124
}
183
125
}
184
126
185
- /**
186
- * Calculate positioning
187
- */
127
+ private _offset ( el ) {
128
+ const box = el . getBoundingClientRect ( ) ;
129
+ const docElem = document . documentElement ;
130
+ return {
131
+ top : box . top + window . pageYOffset - docElem . clientTop ,
132
+ left : box . left + window . pageXOffset - docElem . clientLeft
133
+ } ;
134
+ }
135
+
188
136
_calculatePositioning ( ) {
189
137
// Element or parent is fixed position?
190
- let isFixed = this . $origin . css ( 'position' ) === 'fixed' ;
191
- if ( ! isFixed ) {
192
- let parents = this . $origin . parents ( ) ;
138
+ let isFixed = this . _origin . style . position === 'fixed' ;
139
+ if ( ! isFixed ) {
140
+ let currentElem : any = this . _origin ;
141
+ const parents = [ ] ;
142
+ while ( ( currentElem = currentElem . parentNode ) && currentElem !== document )
143
+ parents . push ( currentElem ) ;
193
144
for ( let i = 0 ; i < parents . length ; i ++ ) {
194
- isFixed = $ ( parents [ i ] ) . css ( 'position' ) == 'fixed' ;
195
- if ( isFixed ) {
196
- break ;
197
- }
145
+ isFixed = parents [ i ] . style . position == 'fixed' ;
146
+ if ( isFixed ) break ;
198
147
}
199
148
}
200
-
201
149
// Calculating origin
202
- let originWidth = this . $origin . outerWidth ( ) ;
203
- let originHeight = this . $origin . outerHeight ( ) ;
150
+ let originWidth = this . _origin . offsetWidth ;
151
+ let originHeight = this . _origin . offsetHeight ;
204
152
let originTop = isFixed
205
- ? this . $origin . offset ( ) . top - M . getDocumentScrollTop ( )
206
- : this . $origin . offset ( ) . top ;
153
+ ? this . _offset ( this . _origin ) . top - M . getDocumentScrollTop ( )
154
+ : this . _offset ( this . _origin ) . top ;
207
155
let originLeft = isFixed
208
- ? this . $origin . offset ( ) . left - M . getDocumentScrollLeft ( )
209
- : this . $origin . offset ( ) . left ;
210
-
156
+ ? this . _offset ( this . _origin ) . left - M . getDocumentScrollLeft ( )
157
+ : this . _offset ( this . _origin ) . left ;
211
158
// Calculating screen
212
159
let windowWidth = window . innerWidth ;
213
160
let windowHeight = window . innerHeight ;
@@ -219,14 +166,12 @@ import { M } from "./global";
219
166
let isTop = originTop <= centerY ;
220
167
let isBottom = originTop > centerY ;
221
168
let isCenterX = originLeft >= windowWidth * 0.25 && originLeft <= windowWidth * 0.75 ;
222
-
223
169
// Calculating tap target
224
170
let tapTargetWidth = this . $el . outerWidth ( ) ;
225
171
let tapTargetHeight = this . $el . outerHeight ( ) ;
226
172
let tapTargetTop = originTop + originHeight / 2 - tapTargetHeight / 2 ;
227
173
let tapTargetLeft = originLeft + originWidth / 2 - tapTargetWidth / 2 ;
228
174
let tapTargetPosition = isFixed ? 'fixed' : 'absolute' ;
229
-
230
175
// Calculating content
231
176
let tapTargetTextWidth = isCenterX ? tapTargetWidth : tapTargetWidth / 2 + originWidth ;
232
177
let tapTargetTextHeight = tapTargetHeight / 2 ;
@@ -236,7 +181,6 @@ import { M } from "./global";
236
181
let tapTargetTextRight = 0 ;
237
182
let tapTargetTextPadding = originWidth ;
238
183
let tapTargetTextAlign = isBottom ? 'bottom' : 'top' ;
239
-
240
184
// Calculating wave
241
185
let tapTargetWaveWidth = originWidth > originHeight ? originWidth * 2 : originWidth * 2 ;
242
186
let tapTargetWaveHeight = tapTargetWaveWidth ;
@@ -279,42 +223,26 @@ import { M } from "./global";
279
223
} ) ;
280
224
}
281
225
282
- /**
283
- * Open TapTarget
284
- */
285
226
open ( ) {
286
- if ( this . isOpen ) {
287
- return ;
288
- }
289
-
227
+ if ( this . isOpen ) return ;
290
228
// onOpen callback
291
229
if ( typeof this . options . onOpen === 'function' ) {
292
- this . options . onOpen . call ( this , this . $origin [ 0 ] ) ;
230
+ this . options . onOpen . call ( this , this . _origin ) ;
293
231
}
294
-
295
232
this . isOpen = true ;
296
233
this . wrapper . classList . add ( 'open' ) ;
297
-
298
234
document . body . addEventListener ( 'click' , this . _handleDocumentClickBound , true ) ;
299
235
document . body . addEventListener ( 'touchend' , this . _handleDocumentClickBound ) ;
300
236
}
301
237
302
- /**
303
- * Close Tap Target
304
- */
305
238
close ( ) {
306
- if ( ! this . isOpen ) {
307
- return ;
308
- }
309
-
239
+ if ( ! this . isOpen ) return ;
310
240
// onClose callback
311
241
if ( typeof this . options . onClose === 'function' ) {
312
- this . options . onClose . call ( this , this . $origin [ 0 ] ) ;
242
+ this . options . onClose . call ( this , this . _origin ) ;
313
243
}
314
-
315
244
this . isOpen = false ;
316
245
this . wrapper . classList . remove ( 'open' ) ;
317
-
318
246
document . body . removeEventListener ( 'click' , this . _handleDocumentClickBound , true ) ;
319
247
document . body . removeEventListener ( 'touchend' , this . _handleDocumentClickBound ) ;
320
248
}
0 commit comments