@@ -9,16 +9,24 @@ import {
9
9
Inject
10
10
} from '@angular/core' ;
11
11
import { DOCUMENT } from '@angular/common' ;
12
+ import { Observable , Subject } from 'rxjs' ;
13
+ import { requestIdleCallbackObservable } from './request-idle-callback' ;
14
+ import { switchMapTo , takeUntil } from 'rxjs/operators' ;
12
15
13
16
const clickElements = new Set < HTMLElement > ( ) ;
14
17
18
+ const eventName : string =
19
+ typeof window !== 'undefined' && typeof window [ 'Hammer' ] !== 'undefined'
20
+ ? 'tap'
21
+ : 'click' ;
22
+
15
23
@Directive ( {
16
24
selector : '[mwlClick]'
17
25
} )
18
26
export class ClickDirective implements OnInit , OnDestroy {
19
27
@Output ( 'mwlClick' ) click = new EventEmitter < MouseEvent > ( ) ; // tslint:disable-line
20
28
21
- private removeListener : ( ) => void ;
29
+ private destroy$ = new Subject ( ) ;
22
30
23
31
constructor (
24
32
private renderer : Renderer2 ,
@@ -33,16 +41,16 @@ export class ClickDirective implements OnInit, OnDestroy {
33
41
'true'
34
42
) ;
35
43
clickElements . add ( this . elm . nativeElement ) ;
36
- const eventName : string =
37
- typeof window !== 'undefined' && typeof window [ 'Hammer' ] !== 'undefined'
38
- ? 'tap'
39
- : 'click' ;
40
- this . removeListener = this . renderer . listen (
41
- this . elm . nativeElement ,
42
- eventName ,
43
- event => {
44
+
45
+ // issue #942 - lazily initialise all click handlers after initial render as hammerjs is slow
46
+ requestIdleCallbackObservable ( )
47
+ . pipe (
48
+ switchMapTo ( this . listen ( ) ) ,
49
+ takeUntil ( this . destroy$ )
50
+ )
51
+ . subscribe ( event => {
44
52
// prevent child click events from firing on parent elements that also have click events
45
- let nearestClickableParent : HTMLElement = event . target ;
53
+ let nearestClickableParent = event . target as HTMLElement ;
46
54
while (
47
55
! clickElements . has ( nearestClickableParent ) &&
48
56
nearestClickableParent !== this . document . body
@@ -54,12 +62,19 @@ export class ClickDirective implements OnInit, OnDestroy {
54
62
if ( isThisClickableElement ) {
55
63
this . click . next ( event ) ;
56
64
}
57
- }
58
- ) ;
65
+ } ) ;
59
66
}
60
67
61
68
ngOnDestroy ( ) : void {
62
- this . removeListener ( ) ;
69
+ this . destroy$ . next ( ) ;
63
70
clickElements . delete ( this . elm . nativeElement ) ;
64
71
}
72
+
73
+ private listen ( ) {
74
+ return new Observable < MouseEvent > ( observer => {
75
+ return this . renderer . listen ( this . elm . nativeElement , eventName , event => {
76
+ observer . next ( event ) ;
77
+ } ) ;
78
+ } ) ;
79
+ }
65
80
}
0 commit comments