mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
perf(tabs): reduce amount of reflows when aligning the ink bar (#2372)
This commit is contained in:
committed by
Kara
parent
e2989b3b98
commit
dab742fe44
@@ -8,7 +8,7 @@
|
||||
|
||||
<div class="md-tab-label-container" #tabListContainer
|
||||
(keydown)="_handleKeydown($event)">
|
||||
<div class="md-tab-list" #tabList role="tablist" (cdkObserveContent)="_updatePagination()">
|
||||
<div class="md-tab-list" #tabList role="tablist" (cdkObserveContent)="_onContentChanges()">
|
||||
<ng-content></ng-content>
|
||||
<md-ink-bar></md-ink-bar>
|
||||
</div>
|
||||
|
||||
+35
-18
@@ -5,7 +5,13 @@ import {
|
||||
NgZone,
|
||||
QueryList,
|
||||
ElementRef,
|
||||
ViewEncapsulation, ContentChildren, Output, EventEmitter, Optional
|
||||
ViewEncapsulation,
|
||||
ContentChildren,
|
||||
Output,
|
||||
EventEmitter,
|
||||
Optional,
|
||||
AfterContentChecked,
|
||||
AfterContentInit,
|
||||
} from '@angular/core';
|
||||
import {RIGHT_ARROW, LEFT_ARROW, ENTER, Dir, LayoutDirection} from '../core';
|
||||
import {MdTabLabelWrapper} from './tab-label-wrapper';
|
||||
@@ -44,7 +50,7 @@ const EXAGGERATED_OVERSCROLL = 60;
|
||||
'[class.md-tab-header-rtl]': "_getLayoutDirection() == 'rtl'",
|
||||
}
|
||||
})
|
||||
export class MdTabHeader {
|
||||
export class MdTabHeader implements AfterContentChecked, AfterContentInit {
|
||||
@ContentChildren(MdTabLabelWrapper) _labelWrappers: QueryList<MdTabLabelWrapper>;
|
||||
|
||||
@ViewChild(MdInkBar) _inkBar: MdInkBar;
|
||||
@@ -106,12 +112,12 @@ export class MdTabHeader {
|
||||
this._tabLabelCount = this._labelWrappers.length;
|
||||
}
|
||||
|
||||
|
||||
// If the selected index has changed, scroll to the label and check if the scrolling controls
|
||||
// should be disabled.
|
||||
if (this._selectedIndexChanged) {
|
||||
this._scrollToLabel(this._selectedIndex);
|
||||
this._checkScrollingControls();
|
||||
this._alignInkBarToSelectedTab();
|
||||
this._selectedIndexChanged = false;
|
||||
}
|
||||
|
||||
@@ -123,18 +129,6 @@ export class MdTabHeader {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Waits one frame for the view to update, then updates the ink bar and scroll.
|
||||
* Note: This must be run outside of the zone or it will create an infinite change detection loop.
|
||||
*/
|
||||
ngAfterViewChecked(): void {
|
||||
this._zone.runOutsideAngular(() => {
|
||||
window.requestAnimationFrame(() => {
|
||||
this._alignInkBarToSelectedTab();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
_handleKeydown(event: KeyboardEvent) {
|
||||
switch (event.keyCode) {
|
||||
case RIGHT_ARROW:
|
||||
@@ -149,6 +143,21 @@ export class MdTabHeader {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Aligns the ink bar to the selected tab on load.
|
||||
*/
|
||||
ngAfterContentInit() {
|
||||
this._alignInkBarToSelectedTab();
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for when the MutationObserver detects that the content has changed.
|
||||
*/
|
||||
_onContentChanges() {
|
||||
this._updatePagination();
|
||||
this._alignInkBarToSelectedTab();
|
||||
}
|
||||
|
||||
/**
|
||||
* Updating the view whether pagination should be enabled or not
|
||||
*/
|
||||
@@ -178,7 +187,7 @@ export class MdTabHeader {
|
||||
_isValidIndex(index: number): boolean {
|
||||
if (!this._labelWrappers) { return true; }
|
||||
|
||||
const tab = this._labelWrappers.toArray()[index];
|
||||
const tab = this._labelWrappers ? this._labelWrappers.toArray()[index] : null;
|
||||
return tab && !tab.disabled;
|
||||
}
|
||||
|
||||
@@ -282,7 +291,10 @@ export class MdTabHeader {
|
||||
* should be called sparingly.
|
||||
*/
|
||||
_scrollToLabel(labelIndex: number) {
|
||||
const selectedLabel = this._labelWrappers.toArray()[labelIndex];
|
||||
const selectedLabel = this._labelWrappers
|
||||
? this._labelWrappers.toArray()[labelIndex]
|
||||
: null;
|
||||
|
||||
if (!selectedLabel) { return; }
|
||||
|
||||
// The view length is the visible width of the tab labels.
|
||||
@@ -359,6 +371,11 @@ export class MdTabHeader {
|
||||
const selectedLabelWrapper = this._labelWrappers && this._labelWrappers.length
|
||||
? this._labelWrappers.toArray()[this.selectedIndex].elementRef.nativeElement
|
||||
: null;
|
||||
this._inkBar.alignToElement(selectedLabelWrapper);
|
||||
|
||||
this._zone.runOutsideAngular(() => {
|
||||
requestAnimationFrame(() => {
|
||||
this._inkBar.alignToElement(selectedLabelWrapper);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user