Skip to content

Instantly share code, notes, and snippets.

@pfeiffer
Created December 7, 2023 22:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pfeiffer/d53bd40a39ee0586f54303e525c60fe2 to your computer and use it in GitHub Desktop.
Save pfeiffer/d53bd40a39ee0586f54303e525c60fe2 to your computer and use it in GitHub Desktop.
Turbo Hover Preloading
class Preloader {
static delay = 100
constructor (element) {
this.element = element
this.element.addEventListener("mouseenter", this.didMouseEnter)
this.element.addEventListener("mouseleave", this.didMouseLeave)
}
didMouseEnter = () => {
if (this.mouseOverTimeout) { return }
this.mouseOverTimeout = setTimeout(this.preload, this.delay)
}
didMouseLeave = () => {
clearTimeout(this.mouseOverTimeout)
this.mouseOverTimeout = null
}
preload = () => {
const event = new CustomEvent("preload", { bubbles: true, cancelable: true })
if(this.element.dispatchEvent(event)) {
Turbo.session.preloader.preloadURL(this.element);
}
}
}
export default class TurboHoverPreloadingObserver {
start () {
this.observer = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
mutation.addedNodes.forEach((node) => {
if (node instanceof Element) {
this.attachPreloadingControllers(node)
}
})
})
})
this.observer.observe(document, { childList: true, subtree: true })
this.attachPreloadingControllers(document)
}
stop () {
this.observer.disconnect()
}
attachPreloadingControllers = (parent) => {
parent.querySelectorAll("a").forEach((linkElement) => {
if (linkElement.preloader) { return }
linkElement.preloader = new Preloader(linkElement)
})
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment