admin管理员组

文章数量:1356815

Currently im trying to implement requestAnimationFrame() in my code. My goal is to observe the current scrollPosition of the window and update a variable constantly.

Code of my Vue Single File Component:

<script>
   data() {
      return {
         scrollPosition: 0
      }
   },
   methods: {
      updateScrollPosition() {
         this.scrollPosition = window.scrollY
         window.requestAnimationFrame(this.updateScrollPosition())
      }
   },
   created() {
      this.updateScrollPosition()
   }
</script>

,js,console,output

I expected that the scrollPosition constanstly changes based on the actual window scroll position. But actually I get InternalError: "too much recursion". So basically I feel like I didnt really understood this requestAnimationFrame() function — need help. Thank you!

Currently im trying to implement requestAnimationFrame() in my code. My goal is to observe the current scrollPosition of the window and update a variable constantly.

Code of my Vue Single File Component:

<script>
   data() {
      return {
         scrollPosition: 0
      }
   },
   methods: {
      updateScrollPosition() {
         this.scrollPosition = window.scrollY
         window.requestAnimationFrame(this.updateScrollPosition())
      }
   },
   created() {
      this.updateScrollPosition()
   }
</script>

https://jsbin./gizamohuxu/edit?html,js,console,output

I expected that the scrollPosition constanstly changes based on the actual window scroll position. But actually I get InternalError: "too much recursion". So basically I feel like I didnt really understood this requestAnimationFrame() function — need help. Thank you!

Share Improve this question asked Sep 2, 2019 at 10:54 gustavgustav 4065 silver badges17 bronze badges 3
  • developer.mozilla/en-US/docs/Web/API/… – curious lad Commented Sep 2, 2019 at 10:58
  • so its not possible with requestAnimationFrame() ? – gustav Commented Sep 2, 2019 at 11:03
  • probably it is, but this is native api for scroll – curious lad Commented Sep 2, 2019 at 12:28
Add a ment  | 

2 Answers 2

Reset to default 4

You directly call updateScrollPosition() in your statement and pass the result to requestAnimationFrame:

window.requestAnimationFrame(this.updateScrollPosition());

You need to pass the function directly to requestAnimationFrame, e.g.:

// pass function to requestAnimationFrame
window.requestAnimationFrame(this.updateScrollPosition);

Then it'll work as expected.

Altough you should use the scroll event if you want to get notified when the user scrolls, you can subscribe to it via addEventListener:

new Vue({
  data() {
    return {
      scrollPosition: 0
    };
  },
  methods: {
    updateScrollPosition() {
      this.scrollPosition = window.scrollY;
    }
  },
  created() {
    window.addEventListener("scroll", this.updateScrollPosition);
  },
  beforeDestroy() {
    // remove listener again
    window.removeEventListener("scroll", this.updateScrollPosition);
  }
});

Also remember to clean up the registered listener with removeEventListener once you don't need it anymore.

I believe implementing this using requestAnimationFrame would actually be worse for browser performance.

Important

The above statement is incorrect. You can use requestAnimationFrame to throttle the scroll event to make it more efficient as seen on MDN.

You essentially created infinite loop and that's why the call stack was exceeded. I would listen to the scroll event using addEventListener on window.

Example

var app = new Vue({
  el: '#app',
  data: {
    message: 'Hello Vue!',
    scrollPosition: 0,
    ticking: false
  },
  methods: {
     updateScrollPosition() {
       this.scrollPosition = window.scrollY;   
       
       if (!this.ticking) {
          window.requestAnimationFrame(function() {
          
          // do something

          this.ticking = false;
        });

          this.ticking = true;
      }
     }
  },
  created() {    
    window.addEventListener('scroll', this.updateScrollPosition);
  }
})
#app {
  position: fixed;
  background: white;
  top: 0;
  left: 0;
  right: 0;
}
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
</head>
<body>
<div id="app">
  {{ message }}
  {{ scrollPosition }}
</div>
  <div>scroll</div>
  <div>scroll</div><div>scroll</div><div>scroll</div><div>scroll</div><div>scroll</div><div>scroll</div><div>scroll</div><div>scroll</div><div>scroll</div><div>scroll</div><div>scroll</div><div>scroll</div><div>scroll</div><div>scroll</div><div>scroll</div><div>scroll</div><div>scroll</div><div>scroll</div><div>scroll</div><div>scroll</div><div>scroll</div><div>scroll</div><div>scroll</div><div>scroll</div><div>scroll</div><div>scroll</div><div>scroll</div><div>scroll</div><div>scroll</div><div>scroll</div><div>scroll</div><div>scroll</div><div>scroll</div><div>scroll</div><div>scroll</div><div>scroll</div><div>scroll</div><div>scroll</div><div>scroll</div><div>scroll</div><div>scroll</div><div>scroll</div><div>scroll</div><div>scroll</div><div>scroll</div><div>scroll</div><div>scroll</div><div>scroll</div><div>scroll</div><div>scroll</div><div>scroll</div><div>scroll</div><div>scroll</div><div>scroll</div><div>scroll</div><div>scroll</div><div>scroll</div><div>scroll</div><div>scroll</div><div>scroll</div><div>scroll</div><div>scroll</div><div>scroll</div><div>scroll</div><div>scroll</div><div>scroll</div><div>scroll</div><div>scroll</div><div>scroll</div><div>scroll</div><div>scroll</div><div>scroll</div><div>scroll</div><div>scroll</div><div>scroll</div><div>scroll</div><div>scroll</div><div>scroll</div><div>scroll</div><div>scroll</div><div>scroll</div><div>scroll</div>

<script src="https://cdnjs.cloudflare./ajax/libs/vue/1.0.16/vue.js"></script>
  
</body>
</html>

本文标签: javascriptObserving scroll position with requestAnimationFrame in VueStack Overflow