4

I've the need to react to window (viewport) scrolling to be able to detect when an element is visible or not.

The final goal is create something SIMILAR but not equal to an infinite scroller.

I want to learn to make it by myself. Do not link me plugins Please, I need to understand Vue.js before constructing over other's plugins.

How can I detect page (windows, or better the viewport) scrolling and resizing using Vue.js?

OR

How can I overseer the vertical position of an element, a div or a span, to react when it's near to be visibile ?

In the doc I found the @scroll, but it react to the scrolling of an element, not of the page.

realtebo
  • 23,922
  • 37
  • 112
  • 189
  • Possible duplicate of https://stackoverflow.com/questions/45822150/how-to-listen-to-the-window-scroll-event-in-a-vuejs-component/55210137#55210137 – agm1984 Nov 03 '20 at 19:35
  • 2
    Sorry, but this question is older than your duplicate candidate... a lot older – realtebo Nov 04 '20 at 14:56

2 Answers2

9

There is a good suggestion here: https://github.com/vuejs/Discussion/issues/324#issuecomment-240978025

I duplicate the code here for posterity.

data () {
  return {
    scrolled: false
  };
},
methods: {
  handleScroll () {
    this.scrolled = window.scrollY > 0;
  }
},
created () {
  window.addEventListener('scroll', this.handleScroll);
},
destroyed () {
  window.removeEventListener('scroll', this.handleScroll);
}
Byscripts
  • 2,578
  • 2
  • 18
  • 25
  • Ehm. could you write how to use it inside `new Vue({ ... });` , please? – realtebo Jun 28 '17 at 14:27
  • 2
    What you mean? If you want to use it inside new Vue({...}), then just insert it inside... And if you want to use it as a Vue module, then export it. – Byscripts Jun 28 '17 at 14:29
  • I got a lot of syntax error if I simply copy/paste your code into new Vue({...}) .... EDIT: Yes, it works... My IDE was warning but obviously webpack fix all problems at the js code doing a transpile, so actually it works. thanks. – realtebo Jun 28 '17 at 14:32
  • 1
    [Edit: Ok, I saw you new answer, so it's ok :)] Oh I see... probably because it's ES6. Try replacing `data ()`, `handleScroll ()`, `created ()` and `destroyed ()` with `data: function ()`, `handleScroll: function ()`, `created: function ()` and `destroyed: function ()` (from memory... I didn't wrote ES5 since a very long time) – Byscripts Jun 28 '17 at 14:35
  • Do anyone knows how to put this in vuex and use only one variable to access scroll position in every component? – Shubham Dubey May 07 '21 at 13:17
2

You need to add a listener to the global scroll event on the window object.

window.addEventListener('scroll', listener)

You can find good advice on how to handle this event properly on MDN: https://developer.mozilla.org/en-US/docs/Web/Events/scroll

You can use Node#getBoundingClientRect to compute whether your node is visible, this method will provide you with the top position of your node within its scrollable container, you can use the offsetTop property alternatively. To do so you have to retrieve the viewport height, which is window.innerHeight is your case, and your current scroll position, which is window.scrollY in your case.

Then you can do something like that:

isVisible = innerHeight - scrollY > offsetTop - scrollY
kketch
  • 673
  • 1
  • 7
  • 10