Skip to content

Instantly share code, notes, and snippets.

@e200
Last active October 25, 2018 15:52
Show Gist options
  • Save e200/15141ed926db213555cd511de6fceaa4 to your computer and use it in GitHub Desktop.
Save e200/15141ed926db213555cd511de6fceaa4 to your computer and use it in GitHub Desktop.
ScrollToTop.vue
<template>
<a id="scroll-to-top"
class="scroll-to-top"
:class="{ 'is-visible': isVisible }"
href="#"
@click.prevent="scrollToTop">
<i class="fa fa-angle-up"></i>
</a>
</template>
<script>
export default {
data() {
return {
/**
* Defines if the button is visible or not
*/
isVisible: false,
/**
* Used to reset the count for the
* button to desappear
*/
visibilityInterval: null,
waitingTime: 7000
}
},
methods: {
/**
* Scroll the `window` to the top
* using `requestAnimationFrame`
* for a smooth scroll.
*
* It works recursively.
*/
scrollToTop() {
const scrollPosition = document.documentElement.scrollTop
if (scrollPosition > 0) {
window.requestAnimationFrame(this.scrollToTop)
window.scrollTo(0, scrollPosition - (scrollPosition / 8))
}
},
/**
* Starts the count the makes
* the button desappear in certain
* time
*/
startVisibilityInterval() {
const context = this
this.visibilityInterval = setTimeout(() => {
context.isVisible = false
}, this.waitingTime)
}
},
mounted() {
const scrollToTopButton = document.querySelector('#scroll-to-top')
const halfOfTheScreenSize = window.outerHeight / 2
let oldScrollPosition = 0
let newScrollPosition = 0
scrollToTopButton.addEventListener(
'mouseover',
() => {
clearInterval(this.visibilityInterval)
}
)
scrollToTopButton.addEventListener(
'mouseleave',
this.startVisibilityInterval
)
// eslint-disable-next-line
window.onscroll = function () {
newScrollPosition = window.scrollY
if (
newScrollPosition > halfOfTheScreenSize &&
newScrollPosition < oldScrollPosition
) {
if (!this.isVisible) {
this.isVisible = true
this.startVisibilityInterval()
}
} else if (this.isVisible) {
this.isVisible = false
}
oldScrollPosition = newScrollPosition
}.bind(this)
}
}
</script>
<style lang="scss" scoped>
#scroll-to-top {
display: flex;
align-items: center;
justify-content: center;
position: fixed;
bottom: 45px;
right: 45px;
width: 45px;
height: 45px;
font-size: 2rem;
visibility: collapse;
opacity: 0;
padding: 20px;
background: #fdfdfd;
border-radius: 5px;
transition: $transition-time;
&:hover {
text-decoration: none;
box-shadow: 0 0 8px rgba($black, .2)
}
&.is-visible {
visibility: visible;
opacity: 1;
}
}
</style>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment