diff --git a/src/lib/sidenav/drawer.ts b/src/lib/sidenav/drawer.ts index e681d0e13dc..f44c6ceee45 100644 --- a/src/lib/sidenav/drawer.ts +++ b/src/lib/sidenav/drawer.ts @@ -41,6 +41,7 @@ import {startWith} from 'rxjs/operators/startWith'; import {takeUntil} from 'rxjs/operators/takeUntil'; import {debounceTime} from 'rxjs/operators/debounceTime'; import {map} from 'rxjs/operators/map'; +import {fromEvent} from 'rxjs/observable/fromEvent'; import {Subject} from 'rxjs/Subject'; import {Observable} from 'rxjs/Observable'; import {matDrawerAnimations} from './drawer-animations'; @@ -119,7 +120,6 @@ export class MatDrawerContent implements AfterContentInit { '[@transform]': '_animationState', '(@transform.start)': '_onAnimationStart($event)', '(@transform.done)': '_onAnimationEnd($event)', - '(keydown)': 'handleKeydown($event)', // must prevent the browser from aligning text based on value '[attr.align]': 'null', '[class.mat-drawer-end]': 'position === "end"', @@ -258,6 +258,7 @@ export class MatDrawer implements AfterContentInit, AfterContentChecked, OnDestr private _focusTrapFactory: FocusTrapFactory, private _focusMonitor: FocusMonitor, private _platform: Platform, + private _ngZone: NgZone, @Optional() @Inject(DOCUMENT) private _doc: any) { this.openedChange.subscribe((opened: boolean) => { @@ -273,6 +274,20 @@ export class MatDrawer implements AfterContentInit, AfterContentChecked, OnDestr this._restoreFocus(); } }); + + /** + * Listen to `keydown` events outside the zone so that change detection is not run every + * time a key is pressed. Instead we re-enter the zone only if the `ESC` key is pressed + * and we don't have close disabled. + */ + this._ngZone.runOutsideAngular(() => { + fromEvent(this._elementRef.nativeElement, 'keydown').pipe( + filter((event: KeyboardEvent) => event.keyCode === ESCAPE && !this.disableClose) + ).subscribe((event) => this._ngZone.run(() => { + this.close(); + event.stopPropagation(); + })); + }); } /** Traps focus inside the drawer. */ @@ -382,17 +397,6 @@ export class MatDrawer implements AfterContentInit, AfterContentChecked, OnDestr }); } - /** - * Handles the keyboard events. - * @docs-private - */ - handleKeydown(event: KeyboardEvent): void { - if (event.keyCode === ESCAPE && !this.disableClose) { - this.close(); - event.stopPropagation(); - } - } - _onAnimationStart(event: AnimationEvent) { this._animationStarted.emit(event); } diff --git a/src/lib/sidenav/sidenav.ts b/src/lib/sidenav/sidenav.ts index 11c75792c0d..c04cc8a7ca1 100644 --- a/src/lib/sidenav/sidenav.ts +++ b/src/lib/sidenav/sidenav.ts @@ -57,7 +57,6 @@ export class MatSidenavContent extends MatDrawerContent { '[@transform]': '_animationState', '(@transform.start)': '_onAnimationStart($event)', '(@transform.done)': '_onAnimationEnd($event)', - '(keydown)': 'handleKeydown($event)', // must prevent the browser from aligning text based on value '[attr.align]': 'null', '[class.mat-drawer-end]': 'position === "end"',