Check if a user has scrolled to the bottom in Vue.js

in Code Write a comment

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 called 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.

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:

Write a Comment

Comment

25 Comments

  1. 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 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.

  2. 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.

  3. 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?!

  4. 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.