More robust page loader
This commit is contained in:
parent
bb555457c6
commit
0d74291075
@ -14,6 +14,7 @@ export default class Application {
|
|||||||
currentPath: string
|
currentPath: string
|
||||||
originalPath: string
|
originalPath: string
|
||||||
lastRequest: XMLHttpRequest | null
|
lastRequest: XMLHttpRequest | null
|
||||||
|
contentInvisible: boolean
|
||||||
onError: (err: Error) => void
|
onError: (err: Error) => void
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
@ -104,26 +105,33 @@ export default class Application {
|
|||||||
// Mark active links
|
// Mark active links
|
||||||
this.markActiveLinks()
|
this.markActiveLinks()
|
||||||
|
|
||||||
let onTransitionEnd = (e: Event) => {
|
let consume = async () => {
|
||||||
|
let html = await request
|
||||||
|
|
||||||
|
if(this.currentPath !== url) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set content
|
||||||
|
this.setContent(html)
|
||||||
|
this.scrollToTop()
|
||||||
|
|
||||||
|
// Fade in listener
|
||||||
|
let onFadedIn: EventListener = (e: Event) => {
|
||||||
// Ignore transitions of child elements.
|
// Ignore transitions of child elements.
|
||||||
// We only care about the transition event on the content element.
|
// We only care about the transition event on the content element.
|
||||||
if(e.target !== this.content) {
|
if(e.target !== this.content) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Outdated response.
|
// Reset the transition ended flag
|
||||||
if(this.currentPath !== url) {
|
this.contentInvisible = false
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove listener after we finally got the correct event.
|
// Remove listener after we finally got the correct event.
|
||||||
this.content.removeEventListener("transitionend", onTransitionEnd)
|
this.content.removeEventListener("transitionend", onFadedIn)
|
||||||
|
}
|
||||||
|
|
||||||
// Wait for the network request to end.
|
this.content.addEventListener("transitionend", onFadedIn)
|
||||||
request.then(html => {
|
|
||||||
// Set content
|
|
||||||
this.setContent(html)
|
|
||||||
this.scrollToTop()
|
|
||||||
|
|
||||||
// Fade animations
|
// Fade animations
|
||||||
this.content.classList.remove(this.fadeOutClass)
|
this.content.classList.remove(this.fadeOutClass)
|
||||||
@ -131,13 +139,39 @@ export default class Application {
|
|||||||
|
|
||||||
// Send DOMContentLoaded Event
|
// Send DOMContentLoaded Event
|
||||||
this.emit("DOMContentLoaded")
|
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.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.content.classList.add(this.fadeOutClass)
|
||||||
this.loading.classList.remove(this.fadeOutClass)
|
this.loading.classList.remove(this.fadeOutClass)
|
||||||
|
}
|
||||||
|
|
||||||
return request
|
return request
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user