From 0d7429107574b549636a4007a04a7779b74893ee Mon Sep 17 00:00:00 2001 From: Eduard Urbach Date: Mon, 2 Apr 2018 22:38:00 +0200 Subject: [PATCH] More robust page loader --- scripts/Application.ts | 80 ++++++++++++++++++++++++++++++------------ 1 file changed, 57 insertions(+), 23 deletions(-) diff --git a/scripts/Application.ts b/scripts/Application.ts index 2d95031e..ac0d573b 100644 --- a/scripts/Application.ts +++ b/scripts/Application.ts @@ -14,6 +14,7 @@ export default class Application { currentPath: string originalPath: string lastRequest: XMLHttpRequest | null + contentInvisible: boolean onError: (err: Error) => void constructor() { @@ -104,40 +105,73 @@ export default class Application { // Mark active links this.markActiveLinks() - let onTransitionEnd = (e: Event) => { - // Ignore transitions of child elements. - // We only care about the transition event on the content element. - if(e.target !== this.content) { - return - } + let consume = async () => { + let html = await request - // Outdated response. if(this.currentPath !== url) { return } - // Remove listener after we finally got the correct event. - this.content.removeEventListener("transitionend", onTransitionEnd) + // Set content + this.setContent(html) + this.scrollToTop() - // Wait for the network request to end. - request.then(html => { - // Set content - this.setContent(html) - this.scrollToTop() + // Fade in listener + let onFadedIn: EventListener = (e: Event) => { + // Ignore transitions of child elements. + // We only care about the transition event on the content element. + if(e.target !== this.content) { + return + } - // Fade animations - this.content.classList.remove(this.fadeOutClass) - this.loading.classList.add(this.fadeOutClass) + // Reset the transition ended flag + this.contentInvisible = false - // Send DOMContentLoaded Event - this.emit("DOMContentLoaded") - }) + // Remove listener after we finally got the correct event. + this.content.removeEventListener("transitionend", onFadedIn) + } + + this.content.addEventListener("transitionend", onFadedIn) + + // Fade animations + this.content.classList.remove(this.fadeOutClass) + this.loading.classList.add(this.fadeOutClass) + + // Send DOMContentLoaded Event + this.emit("DOMContentLoaded") } - this.content.addEventListener("transitionend", onTransitionEnd) + if(this.contentInvisible) { + consume() + } else { + // Fade out listener + let onFadedOut: EventListener = (e: Event) => { + // Ignore transitions of child elements. + // We only care about the transition event on the content element. + if(e.target !== this.content) { + return + } - this.content.classList.add(this.fadeOutClass) - this.loading.classList.remove(this.fadeOutClass) + this.contentInvisible = true + + // Remove listener after we finally got the correct event. + this.content.removeEventListener("transitionend", onFadedOut) + + // Outdated response. + if(this.currentPath !== url) { + return + } + + // Wait for the network request to end. + consume() + } + + this.content.addEventListener("transitionend", onFadedOut) + + // Add fade out class + this.content.classList.add(this.fadeOutClass) + this.loading.classList.remove(this.fadeOutClass) + } return request }