当前,我正在尝试在我的代码中实现requestAnimationFrame()
。我的目标是观察窗口的当前scrollPosition并不断更新变量。
我的Vue单个文件组件的代码:
<script>
data() {
return {
scrollPosition: 0
}
},
methods: {
updateScrollPosition() {
this.scrollPosition = window.scrollY
window.requestAnimationFrame(this.updateScrollPosition())
}
},
created() {
this.updateScrollPosition()
}
</script>
https://jsbin.com/gizamohuxu/edit?html,js,console,output
我希望scrollPosition会根据窗口的实际滚动位置而不断变化。但是实际上我得到InternalError: "too much recursion"
。因此,基本上我觉得我不太了解此requestAnimationFrame()
函数-需要帮助。谢谢!
答案 0 :(得分:1)
您直接在语句中调用updateScrollPosition()
并将结果传递给requestAnimationFrame
:
window.requestAnimationFrame(this.updateScrollPosition());
您需要将函数直接传递给requestAnimationFrame
,例如:
// pass function to requestAnimationFrame
window.requestAnimationFrame(this.updateScrollPosition);
然后它将按预期工作。
如果您想在用户滚动时得到通知,则应该使用scroll
事件,但是您可以通过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);
}
});
也请记住,一旦不再需要使用removeEventListener
清理注册的侦听器。
答案 1 :(得分:0)
我相信使用 requestAnimationFrame
实现此功能实际上会降低浏览器的性能。
以上说法不正确。您可以使用requestAnimationFrame
来限制滚动事件,使其更有效,如MDN所示。
您实质上创建了无限循环,这就是超出调用堆栈的原因。我会使用scroll
上的addEventListener
来监听window
事件。
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.com/ajax/libs/vue/1.0.16/vue.js"></script>
</body>
</html>