This snippet will be useful for those trying to implement an infinite scroll in Vue.js or load next article when user reaches the bottom of the page.
I came up with a working solution and I wanted to share it with you.
How to find when the user is at the bottom of the page
To achieve that create a new function scroll
and place it within the methods
block. This function will calculate if the page offset is equal to the page height. Here is an example:
scroll () {
window.onscroll = () => {
let bottomOfWindow = Math.max(window.pageYOffset, document.documentElement.scrollTop, document.body.scrollTop) + window.innerHeight === document.documentElement.offsetHeight
if (bottomOfWindow) {
this.scrolledToBottom = true // replace it with your code
}
}
}
Call this function in the mounted()
function.
mounted () {
this.scroll()
}
Now you’ll know when the user scrolls to the bottom. You may want to declare a scrolledToBottom
boolean in the data object and use it in your template. Or you can create a function that will load the next page and place it within the scroll
function.
Full example (added on 24 of March 2019):
Vue.js
new Vue({
el: "#app",
data: {
scrolledToBottom: false
},
methods: {
scroll () {
window.onscroll = () => {
let bottomOfWindow = Math.max(window.pageYOffset, document.documentElement.scrollTop, document.body.scrollTop) + window.innerHeight === document.documentElement.offsetHeight
if (bottomOfWindow) {
this.scrolledToBottom = true // replace it with your code
}
}
}
},
mounted () {
this.scroll()
}
})
HTML
<div id="app">
<div class="sticky">
Scrolled to bottom: {{ scrolledToBottom }}
</div>
</div>
CSS
body {
background: #20262E;
padding: 20px;
}
#app {
background: #fff;
height: 200vh;
}
.sticky {
position: sticky;
top: 0;
}
https://jsfiddle.net/fgczx4w8/
UPDATE: 20 May 2019
Some users reported that the example above is only working in Chrome. After a quick investigation, I’ve found a bug in the CSS element “position: sticky”. It’s not working properly in Safari and Firefox. Sorry about that. Here’s an updated example, which works in other browsers.
UPDATE: 2021
If you’re experiencing problems, you can check another solution here.
If you find it useful, please let me know in the comments below.
Make sure you also check how to do Vue.js polling using setInterval() and know the difference between LocalStorage vs SessionStorage vs Cookies.
Incoming search terms:
Saved my day! Thank you!
I’m glad it worked for you 🙂
Hey Renat I tried this solution but it only checks if the page has been scrolled to the top and not the bottom. It seems to be inverse.
Hey Desmond! What browser are you using? I’ve added a full example and a link to JSFiddle. Let me know if it works for you.
Hi Renat
I was having the same problem as Desmond, with Chrome and Firefox.
Removing “margin: none” from the html element sorted with Firefox, but Chrome doesn’t do anything now.
I using Vue, if that helpd
Renat
Regarding my previous comment, I’ve reapplied the margin and Firefox is still working, absolutely fine to be honest. Also meant to say use a Vue for “___ in___”. Chrome still not playing
Hi David,
Thanks for a detailed explanation. After a quick investigation, I’ve found an issue with CSS. Replacing “position: sticky” with “position: fixed” fixed the problem that you and other users reported.
Please check the example above and let me know if it works for you: https://renatello.com/check-if-a-user-has-scrolled-to-the-bottom-in-vue-js/#fixed
Cheers,
Renat
Hi Renat
Sorry about the delay in getting back. The position sticky didn’t work on the same computer (Linux Manjaro), but on a different computer (OS Linux Mint) it worked with or without it.
Not sure if it’s a browser issue, I’m having a problem updating on Manjaro. However, thinking of replacing it with Mint.
Before I do: If you’ve any suggestions that may help others, I’m willing to give it a try
Me again
Damn, just noticed you said replace sticky with fixed. That screws it up on the computer it was working on
Hi David
What happens when you replace sticky with fixed on the computer it was working on? This could be a caching issue. If you open a JSFiddle example (https://jsfiddle.net/renatello/5xuwfrts/6/) in the incognito mode and tell me if it’s working there that’d be awesome. Also, screenshots will help us debug it.
I haven’t tested it on any Linux distros but I know that “position: fixed” is supported by all browsers, starting from IE6. Although JSFiddle itself may not be working on some distros other users should be able to copy and paste the code above and replace position sticky with sticky.
And if the page does not scroll as it does to set true.
Hi Leandro, this example only works for scrollable pages.
Using Chrome it only returns true at the top of the page
Hi Vincent,
I’ve just replied to David (see his comment above). There was a CSS issue, I’ve replaced “position: sticky” with “position: fixed” and it fixed the problem. Let me know if this example works for you:
https://renatello.com/check-if-a-user-has-scrolled-to-the-bottom-in-vue-js/#fixed
Cheers,
Renat
I tested it on my monitor and it worked, but when I tested it on my laptop screen, it did not work …
Hey Flavio, have you tested the latest update? https://renatello.com/check-if-a-user-has-scrolled-to-the-bottom-in-vue-js/#update-20-may-2019
Thank you for sharing.:)
You’re very welcome! 😉
Well done mate!
I did similar stuff in Jquery but unfortunately had no idea how to make this in Vue.
I was looking for this solution for many hours, of course there are so many plugins for this, but most of them work in strange way…
It is what I have been looking for.
Thank you so much.
You are very welcome!
I agree that it’s better to write a custom code rather than use an npm package. I’m glad it worked for you.
Hey, thanks for the article, I have a slight problem, If I enter some action when the user reaches the end of the window the action happens which is great. However, it doesn’t happen when reaching the end but when scrolling from bottom to top.
Do you know how to fix this?!
Also: I’m not using your css but I still have position:fixed; on my material design header element.
Hey Tom! Does the example above (see the “Result” tab here https://renatello.com/check-if-a-user-has-scrolled-to-the-bottom-in-vue-js/#update-20-may-2019 or https://jsfiddle.net/renatello/5xuwfrts/6/) work the opposite way? I’ve tested it on a Mac (Chrome, Safari, FF) and it works as expected.
Could you please share your browser/version/OS?
Hey so, I want to add an element and scroll down in a div element with overflow: auto. I also want it so if the user scrolls up and a new element is added, it shouldn’t scroll down. Help is appreciated.
Hey Saawal! Could you please share your code in some playground like JSFiddle? I should be able to help you then.
hey Renat, how to change offsetheight after every time we hit bottom
thank you so much
Hi Brandon, you’re very welcome!
I’ve explained how to do that in this article https://renatello.com/vue-js-infinite-scroll/. Hope it helps!
it’s working in reverse for me instead of page scroll to bottom it’s working on page scroll to top. am using it without the css style tell me how it will work without the css and am using it in vuejs with chrome browser. thank you
Hi Shami, replace this line:
with these two lines (also add a #bottom-marker to your html part):
and add this method:
ty
ym!
Thank you for this awesome code! 🙂
You’re welcome, Gab!
Well Firstly i want to thank you for your sharing.
i have used this code in one page but its working on the others page.
I mean i just want to use that in my home page not in the description page.
What should i do now?
I am using this in nuxt application.
Thank you
Hi Tanzil! You’re welcome!
You can either check if the route name is equal to ‘homepage’ or place this code inside your homepage component.
Let me know if it works!
Thanks Man!It Works.I just make a condition if the route path is equal to my home page then data will be added.
but I do not understand why this happen?
i place this code in my home page and call the function in the home page mounted life-cycle hook.even i call the function in destroyed hook also.
Can you have any explanation?
Thanks Again
You’re doing everything right!
Do you mind sharing your homepage component code?
I’ll be able to check if there’re any errors.
Cheers
From a mobile browser this code does not work. Please have a look.
Thanks, will do
did you watch this issue?
I haven’t watched it yet
Thank you, Renat. It’s very useful
You’re very welcome, Muhammad!
Thanks for the explanation. I’ve been searching for hours on a version for a div element. It’s a v-list within a v-dialog (Vuetify).
I don’t know if it cannot trigger the scroll event on v-for elements or if is there any other issue with nested components.
I have exactly the same issue that’s described here https://stackoverflow.com/questions/59603315/how-to-detect-when-a-user-scrolls-to-the-bottom-of-a-div-vue
But there is no answer at the moment…