我有多个冲突状态,导致导航项目显示并在滚动后消失。在尝试检查较小的设备之前,滚动事件一直运行良好。似乎checkWidth
中定义的状态导致显示导航项。
在这种情况下是否有更好的方法来处理多个状态?因此,它们仅在应有的状态下触发。任何帮助表示赞赏。
constructor(props) {
super(props);
this.state = {
isTop: true,
};
}
onScroll(isTop) {
this.setState({ isTop });
}
componentDidMount() {
this.updateWindowDimensions();
window.addEventListener('resize', this.updateWindowDimensions);
document.addEventListener('scroll', () => {
const isTop = window.scrollY < window.innerHeight - 50;
if (isTop !== this.state.isTop) {
this.onScroll(isTop);
}
});
this.checkWidth = () => {
const match = window.matchMedia(`(max-width: 768px)`);
if (match) {
this.setState({isTop: false});
}
};
this.checkWidth();
window.addEventListener('resize', this.checkWidth);
}
答案 0 :(得分:0)
您可以使用debounce。
例如,使用此工具,如果您在0.3s内多次调用滚动事件中侦听的函数,则在停止滚动后仅执行一次:
var efficientScroll = debounce(function() {...}, 250);
为什么使用两个不同的函数监听resize
事件。必要吗?也许您也可以改善它。并同时应用防抖功能。
答案 1 :(得分:0)
在移动设备上,方法checkWidth()
会将isTop
设置为false,即使在顶部。这可能会造成混淆。
我认为基于isTop
和isNarrowWidth
这两个状态属性来控制导航菜单的可见性更为有意义。
或:您可以将isTop
更改为navMenuVisible
,并根据window.scrollY
和window.matchMedia()
的值来计算此状态属性。这基本上将checkWidth()
和您的onScroll回调合并到一个方法中。
(而且我会将所有这些逻辑从document.addEventListener
回调移动到onScroll()
。这不是必需的,但是将所有发生的事情放在此方法的内部滚动是有意义的。)>