在 React.js 中滚动时隐藏菜单
在本教程中,我将讲解如何创建一个在页面滚动时隐藏或显示的导航栏。这是一个React.js版本,它使用组件的State来随时了解导航栏的当前状态。
组件
现在我们来看看组件需要哪些部分。首先,正如我们所说,我们将在State中保存滚动的位置,我们将在State中创建一个新值constructor()
,该值将取页面偏移量的初始值。
当然,我们还需要render()
一个返回nav
包含所有导航栏项的方法。首先看一下:
import React, { Component } from "react";
import classnames from "classnames";
export default class Navbar extends Component {
constructor(props) {
super(props);
this.state = {
prevScrollpos: window.pageYOffset,
visible: true
};
}
render() {
return (
<nav
className={classnames("navbar", {
"navbar--hidden": !this.state.visible
})}
>
<a href="#">Item 1</a>
<a href="#">Item 2</a>
<a href="#">Item 3</a>
</nav>
);
}
}
这是 CSS:
.navbar {
width: 100%;
padding: 10px;
position: fixed;
top: 0;
transition: top 0.6s;
}
.navbar--hidden {
top: -50px;
}
完美!我们的组件已经可以在浏览器中使用了,只是还缺少我们想要的行为。那就开始吧!
首先,我们需要实现隐藏或显示导航栏的函数。它会像事件一样被调用。它会根据我们向上滚动还是向下滚动来判断当前偏移量是大于还是小于之前的偏移量。如果偏移量大于,则表示向上滚动,因此它会显示菜单。反之,它会隐藏菜单。此显示/隐藏行为由visible状态变量管理。
handleScroll = () => {
const { prevScrollpos } = this.state;
const currentScrollPos = window.pageYOffset;
const visible = prevScrollpos > currentScrollPos;
this.setState({
prevScrollpos: currentScrollPos,
visible
});
};
现在函数已经完成了。但我们需要在用户每次滚动屏幕时调用它。我们将使用生命周期方法来在滚动时添加和删除该监听器。
componentDidMount() {
window.addEventListener("scroll", this.handleScroll);
}
componentWillUnmount() {
window.removeEventListener("scroll", this.handleScroll);
}
这样,我们的组件就完成了。接下来,我会展示完整的代码。希望你喜欢,我会更频繁地更新内容。期待下次再见!
import React, { Component } from "react";
import classnames from "classnames";
export default class Navbar extends Component {
constructor(props) {
super(props);
this.state = {
prevScrollpos: window.pageYOffset,
visible: true
};
}
// Adds an event listener when the component is mount.
componentDidMount() {
window.addEventListener("scroll", this.handleScroll);
}
// Remove the event listener when the component is unmount.
componentWillUnmount() {
window.removeEventListener("scroll", this.handleScroll);
}
// Hide or show the menu.
handleScroll = () => {
const { prevScrollpos } = this.state;
const currentScrollPos = window.pageYOffset;
const visible = prevScrollpos > currentScrollPos;
this.setState({
prevScrollpos: currentScrollPos,
visible
});
};
render() {
return (
<nav
className={classnames("navbar", {
"navbar--hidden": !this.state.visible
})}
>
<a href="#">Item 1</a>
<a href="#">Item 2</a>
<a href="#">Item 3</a>
</nav>
);
}
}