Skip to content

Instantly share code, notes, and snippets.

@lmiller1990
Created December 7, 2019 08:45
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 lmiller1990/f69e961f80672ac460ece4ac042968e1 to your computer and use it in GitHub Desktop.
Save lmiller1990/f69e961f80672ac460ece4ac042968e1 to your computer and use it in GitHub Desktop.
import Vue from 'vue'
interface IMarkers {
progressStartMarker: HTMLElement | null
progressEndMarker: HTMLElement | null
}
interface IData extends IMarkers {
percent: number
scrollEvent: ((this: Window, ev: Event) => void) | null
}
export default Vue.extend({
name: 'Progress',
data(): IData {
return {
percent: 0,
scrollEvent: null,
progressStartMarker: null,
progressEndMarker: null,
}
},
mounted() {
this.progressStartMarker = document.querySelector<HTMLElement>('#progress-marker-start')
this.progressEndMarker = document.querySelector<HTMLElement>('#progress-marker-end')
if (!this.progressStartMarker || !this.progressEndMarker) {
throw Error('Progress markers not found')
}
window.addEventListener('scroll', () => {
this.getScrollPercentage(this.progressStartMarker!, this.progressEndMarker!)
})
},
methods: {
getScrollPercentage(startMarker: HTMLElement, endMarker: HTMLElement): void {
const offsetFromTop = this.getPosRelativeToBody(startMarker)
const total = this.getPosRelativeToBody(endMarker) - offsetFromTop - window.innerHeight
const progress = (((window.scrollY - offsetFromTop) / total) * 100)
this.percent = progress
},
getPosRelativeToBody(el: HTMLElement): number {
return Math.abs(
document.documentElement.getBoundingClientRect().top - el.getBoundingClientRect().top,
);
},
}
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment