fix(header): avoid flicker on collapsible header load (#19682)

* fix flicker on collapse load

* remove old test
This commit is contained in:
Liam DeBeasi
2019-10-29 14:36:26 -04:00
committed by GitHub
parent 39fb8f6720
commit 0a7aae28a7
3 changed files with 33 additions and 28 deletions

View File

@ -51,8 +51,8 @@
padding-bottom: 13px;
}
ion-toolbar.in-toolbar ion-title,
ion-toolbar.in-toolbar ion-buttons {
.header-collapse-main ion-toolbar.in-toolbar ion-title,
.header-collapse-main ion-toolbar.in-toolbar ion-buttons {
transition: all 0.2s ease-in-out;
}

View File

@ -2,7 +2,7 @@ import { Component, ComponentInterface, Element, Host, Prop, h, readTask, writeT
import { getIonMode } from '../../global/ionic-global';
import { cloneElement, createHeaderIndex, handleContentScroll, handleToolbarIntersection, setHeaderActive } from './header.utils';
import { cloneElement, createHeaderIndex, handleContentScroll, handleToolbarIntersection, setHeaderActive, setToolbarBackgroundOpacity } from './header.utils';
/**
* @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
*/
@ -19,6 +19,7 @@ export class Header implements ComponentInterface {
private scrollEl?: HTMLElement;
private contentScrollCallback?: any;
private intersectionObserver?: any;
private collapsibleMainHeader?: HTMLElement;
@Element() el!: HTMLElement;
@ -77,6 +78,11 @@ export class Header implements ComponentInterface {
this.scrollEl.removeEventListener('scroll', this.contentScrollCallback);
this.contentScrollCallback = undefined;
}
if (this.collapsibleMainHeader) {
this.collapsibleMainHeader.classList.remove('header-collapse-main');
this.collapsibleMainHeader = undefined;
}
}
private async setupCollapsibleHeader(contentEl: HTMLIonContentElement | null, pageEl: Element | null) {
@ -84,18 +90,18 @@ export class Header implements ComponentInterface {
this.scrollEl = await contentEl.getScrollElement();
readTask(() => {
const headers = pageEl.querySelectorAll('ion-header');
const mainHeader = Array.from(headers).find((header: any) => header.collapse !== 'condense') as HTMLElement | undefined;
this.collapsibleMainHeader = Array.from(headers).find((header: any) => header.collapse !== 'condense') as HTMLElement | undefined;
if (!mainHeader || !this.scrollEl) { return; }
if (!this.collapsibleMainHeader) { return; }
const mainHeaderIndex = createHeaderIndex(mainHeader);
const mainHeaderIndex = createHeaderIndex(this.collapsibleMainHeader);
const scrollHeaderIndex = createHeaderIndex(this.el);
if (!mainHeaderIndex || !scrollHeaderIndex) { return; }
setHeaderActive(mainHeaderIndex, false);
setToolbarBackgroundOpacity(mainHeaderIndex.toolbars[0], 0);
readTask(() => {
const mainHeaderHeight = mainHeaderIndex.el.clientHeight;
@ -109,7 +115,6 @@ export class Header implements ComponentInterface {
const toolbarIntersection = (ev: any) => { handleToolbarIntersection(ev, mainHeaderIndex, scrollHeaderIndex); };
this.intersectionObserver = new IntersectionObserver(toolbarIntersection, { threshold: [0.25, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1], rootMargin: `-${mainHeaderHeight}px 0px 0px 0px` });
this.intersectionObserver.observe(scrollHeaderIndex.toolbars[0].el);
});
/**
* Handle scaling of large iOS titles and
@ -117,12 +122,14 @@ export class Header implements ComponentInterface {
* in primary header
*/
this.contentScrollCallback = () => { handleContentScroll(this.scrollEl!, scrollHeaderIndex); };
this.scrollEl.addEventListener('scroll', this.contentScrollCallback);
this.scrollEl!.addEventListener('scroll', this.contentScrollCallback);
});
writeTask(() => {
cloneElement('ion-title');
cloneElement('ion-back-button');
this.collapsibleMainHeader!.classList.add('header-collapse-main');
});
this.collapsibleHeaderInitialized = true;

View File

@ -45,7 +45,7 @@ export const createHeaderIndex = (headerEl: HTMLElement | undefined): HeaderInde
innerTitleEl: (ionTitleEl) ? ionTitleEl.shadowRoot!.querySelector('.toolbar-title') : null,
ionButtonsEl: Array.from(toolbar.querySelectorAll('ion-buttons')) || []
} as ToolbarIndex;
}) || [[]]
}) || []
} as HeaderIndex;
};
@ -60,7 +60,7 @@ export const handleContentScroll = (scrollEl: HTMLElement, scrollHeaderIndex: He
});
};
const setToolbarBackgroundOpacity = (toolbar: ToolbarIndex, opacity: number | undefined) => {
export const setToolbarBackgroundOpacity = (toolbar: ToolbarIndex, opacity: number | undefined) => {
if (opacity === undefined) {
toolbar.background.style.removeProperty('--opacity');
} else {
@ -124,13 +124,11 @@ export const handleToolbarIntersection = (ev: any, mainHeaderIndex: HeaderIndex,
};
export const setHeaderActive = (headerIndex: HeaderIndex, active = true) => {
writeTask(() => {
if (active) {
headerIndex.el.classList.remove('header-collapse-condense-inactive');
} else {
headerIndex.el.classList.add('header-collapse-condense-inactive');
}
});
};
export const scaleLargeTitles = (toolbars: ToolbarIndex[] = [], scale = 1, transition = false) => {