有一个需求:一个元素块A本来在页面中的正常位置,随着滚动条向下滚动到该元素块时变为固定在浏览器顶端,当滚动条向上滚动到元素块A时又恢复到原来的位置。
解决方法:
- 我们首先在react组件中添加一个boolean类型的状态
needFixed
,用于判断该元素块A是否需要固定。 - 然后在通过
document.getElementById('A_ID').offsetTop
获取需要固定的元素块A距离页面顶部的距离X
。 - 利用
window.onscroll()
函数来监控滚动条的滚动事件,从Math.max(document.body.scrollTop, document.documentElement.scrollTop)
这个值来得到滚动条的具体滚动值Y
。 - 当
Y >= X
时,将状态needFixed
的值设为true
,并且元素块A的样式变为position:fixed
,其他情况下保持不变即可。
伪代码:
constructor(){
super()
this.state = {
needFixed: false
}
}
//在适当的地方引用someFunction函数,比如在获取数据成功时的函数中
someFunction = () => {
const fixedTop = document.getElementById('A_ID').offsetTop
window.onscroll = () => {
let scrollTop = Math.max(document.body.scrollTop, document.documentElement.scrollTop)
const {needFixed} = this.state
//控制元素块A随鼠标滚动固定在顶部
if (scrollTop >= fixedTop) {
!needFixed && this.setState({ needFixed: true })
} else if (scrollTop < fixedTop) {
needFixed && this.setState({ needFixed: false })
}
}
}
//---------------------------------------------------------------------------------
//HTML
<div className={needFixed ? styles.aFixed : styles.a} id={'A_ID'}>
xxxxxxxxxxxxxxx
</div>
//---------------------------------------------------------------------------------
//CSS
.a-fixed {
position: fixed;
}
这里建议当元素块A变为fixed时,页面中添加一个和元素块A大小相同的空白div来取代原有的元素块A,从而使页面不会因为元素块A的定位变化而发生改变。
{//当元素块A为fixed时,脱离文档流,用相同高度的空div填充
fixed && <div id={'block'} style={{ height: `${document.getElementById('A_ID').clientHeight}px` }}></div>
}
一些HTML的定位属性可以参考:html中offsetTop、clientTop、scrollTop、offsetTop各属性介绍