I want to listen to the window scroll event in my Vue component. Here is what I tried so far:
<my-component v-on:scroll="scrollFunction"> ... </my-component>
With the scrollFunction(event)
being defined in my component methods but it doesn't seem to work.
Anyone has any idea how to do this?
Thanks!
We can trigger events on an element with Vue. js by assigning a ref to the element we want to trigger events for. Then we can call methods on the element assigned to the ref to trigger the event.
To get or set the scroll position of an element, you follow these steps: First, select the element using the selecting methods such as querySelector() . Second, access the scroll position of the element via the scrollLeft and scrollTop properties.
$v is an object that calls vuelidate (at the time of writing the comment, supported in version Vue. js 2.0), which is intended to check every input, which is made in a non-html form.
Actually I found a solution. I add an event listener on the scroll
event when the component is created and remove the event listener when the component is destroyed.
export default { created () { window.addEventListener('scroll', this.handleScroll); }, destroyed () { window.removeEventListener('scroll', this.handleScroll); }, methods: { handleScroll (event) { // Any code to be executed when the window is scrolled } } }
Hope this helps!
In my experience, using an event listener on scroll can create a lot of noise due to piping into that event stream, which can cause performance issues if you are executing a bulky handleScroll
function.
I often use the technique shown here in the highest rated answer, but I add debounce on top of it, usually about 100ms
yields good performance to UX ratio.
Here is an example using the top-rated answer with Lodash debounce added:
import debounce from 'lodash/debounce'; export default { methods: { handleScroll(event) { // Any code to be executed when the window is scrolled this.isUserScrolling = (window.scrollY > 0); console.log('calling handleScroll'); } }, mounted() { this.handleDebouncedScroll = debounce(this.handleScroll, 100); window.addEventListener('scroll', this.handleDebouncedScroll); }, beforeDestroy() { // I switched the example from `destroyed` to `beforeDestroy` // to exercise your mind a bit. This lifecycle method works too. window.removeEventListener('scroll', this.handleDebouncedScroll); } }
Try changing the value of 100
to 0
and 1000
so you can see the difference in how/when handleScroll
is called.
BONUS: You can also accomplish this in an even more concise and reuseable manner with a library like vue-scroll
. It is a great use case for you to learn about custom directives in Vue if you haven't seen those yet. Check out https://github.com/wangpin34/vue-scroll.
This is also a great tutorial by Sarah Drasner in the Vue docs: https://vuejs.org/v2/cookbook/creating-custom-scroll-directives.html
In vue3 you should use unmounted or beforeUnmount, instead of beforeDestroy
.
Lifecycle hook beforeDestroy is not emitted in Vue3
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With