需要观察滚动
Need to observe scroll
我正在构建一个包含大量动画的登录页面。当我需要为某些东西设置动画时,我会为滚动创建一个事件侦听器并附加 onScroll
函数,该函数通过设置状态来触发我的动画。
我目前创建了不到 10 个侦听器和 10 个函数来检查状态。
我想创建一个使用 1 个事件侦听器的实体,然后我的所有着陆页组件都应该订阅并获得位置。
我该怎么做?
我正在使用 ES6 和 React。
我的一些代码:
componentDidMount() {
this.toggleAppBar();
addScrollEventListener(this.handleOnTopScroll);
addScrollEventListener(this.handleFirstScroll);
}
handleOnTopScroll = () => {
let scrollTop = document.body.scrollTop
if (scrollTop === 0) {
this.toggleAppBar();
}
}
handleFirstScroll = () => {
let scrollTop = document.body.scrollTop
//console.log(scroll);
if (!scroll) {
this.toggleAppBar();
scroll = true
return
}
if (scrollTop === 0) {
scroll = false
}
}
解决方案按要求工作,但我需要为其他组件添加更多的侦听器
使用纯 JS,您可以使用 element.onscroll
事件来监听特定元素上的滚动事件。
如果 jQuery 可用,您可以考虑使用 jQuery 的 scroll()
事件。
我们在公司网站上做了类似的事情,滚动时有一些复杂的动画。我们想出的解决方案是规范化父组件上的滚动,这样 0 scroll = 0 和完全滚动将等于 1。我们将 "animationProgress" 传递给子组件,它可以确定如何以及何时进行动画处理。
为此,我们使用以下内容:
calculateAnimationProgress (target) {
return mapRange(target.scrollTop, 0, target.scrollHeight - window.innerHeight, 0, 1);
}
//Utility function to map a value to it's corelated value within a given range
const mapRange = (value, inMin, inMax, outMin, outMax) => (value - inMin) * (outMax - outMin) / (inMax - inMin) + outMin;
这为我们提供了从 0 到 1 的标准化滚动,因此如果高度发生变化,您将始终有一个已知范围,尽管您可能需要重新计算 window 调整大小等。
在您的子组件中,您可以调整性能,只允许它们在您的 "animationProgress" 给定范围内时重新渲染。
shouldComponentUpdate (nextProps) {
return isInRange(nextProps.animationProgress, 0, 1);
}
//Utility function returns boolean if value within a given range
const isInRange = (val, min, max) => {
return val >= min && val <= max;
}
希望对您有所帮助。您可以在 http://redshiftdigital.com
查看我们通过这种方法得出的结果
我正在构建一个包含大量动画的登录页面。当我需要为某些东西设置动画时,我会为滚动创建一个事件侦听器并附加 onScroll
函数,该函数通过设置状态来触发我的动画。
我目前创建了不到 10 个侦听器和 10 个函数来检查状态。
我想创建一个使用 1 个事件侦听器的实体,然后我的所有着陆页组件都应该订阅并获得位置。
我该怎么做? 我正在使用 ES6 和 React。
我的一些代码:
componentDidMount() {
this.toggleAppBar();
addScrollEventListener(this.handleOnTopScroll);
addScrollEventListener(this.handleFirstScroll);
}
handleOnTopScroll = () => {
let scrollTop = document.body.scrollTop
if (scrollTop === 0) {
this.toggleAppBar();
}
}
handleFirstScroll = () => {
let scrollTop = document.body.scrollTop
//console.log(scroll);
if (!scroll) {
this.toggleAppBar();
scroll = true
return
}
if (scrollTop === 0) {
scroll = false
}
}
解决方案按要求工作,但我需要为其他组件添加更多的侦听器
使用纯 JS,您可以使用 element.onscroll
事件来监听特定元素上的滚动事件。
如果 jQuery 可用,您可以考虑使用 jQuery 的 scroll()
事件。
我们在公司网站上做了类似的事情,滚动时有一些复杂的动画。我们想出的解决方案是规范化父组件上的滚动,这样 0 scroll = 0 和完全滚动将等于 1。我们将 "animationProgress" 传递给子组件,它可以确定如何以及何时进行动画处理。
为此,我们使用以下内容:
calculateAnimationProgress (target) {
return mapRange(target.scrollTop, 0, target.scrollHeight - window.innerHeight, 0, 1);
}
//Utility function to map a value to it's corelated value within a given range
const mapRange = (value, inMin, inMax, outMin, outMax) => (value - inMin) * (outMax - outMin) / (inMax - inMin) + outMin;
这为我们提供了从 0 到 1 的标准化滚动,因此如果高度发生变化,您将始终有一个已知范围,尽管您可能需要重新计算 window 调整大小等。
在您的子组件中,您可以调整性能,只允许它们在您的 "animationProgress" 给定范围内时重新渲染。
shouldComponentUpdate (nextProps) {
return isInRange(nextProps.animationProgress, 0, 1);
}
//Utility function returns boolean if value within a given range
const isInRange = (val, min, max) => {
return val >= min && val <= max;
}
希望对您有所帮助。您可以在 http://redshiftdigital.com
查看我们通过这种方法得出的结果