吸附原理
工作任務需求,某個單一標誌性組件需要在頁面滾動時吸附到窗口頂部,之前利用原生js實現過,基本原理是:
當滾動條相對於頁面的距離大於元素高度時,設置該元素的定位爲fixed。
API
使用的基本API是:
1. 獲取當前窗口滾動條相對頁面的長度,
- document.body.scrollTop //chrome
- document.documentElement.scrollTop//ie678
以上兩個api沒有兼容器,但是好處是當一個有效時另一個的值爲0,所以可以取兩者和或者去最大值來獲取真正的滾動條相對頁面的長度。
2. 獲取要吸附元素距離頁面頂部距離
- document.getElementById(“id”).offsetTop //其中id爲組件id
3. 窗口滾動監聽函數
- window.onscroll
react實現
在react中實現與原生html類似,主要是在合適的地方對窗口滾動函數進行監聽。具體代碼如下
import React, { Component } from "react";
import style from "./MaterialOverview.scss"
import { Switch, Button } from "antd";
class MaterialOverview extends Component {
constructor(props) {
super(props)
this.state = {
eleFixedTop: 0,//元素或者組件距離頁面頂部的距離
fixed: false,//吸附標誌位
}
}
// 頁面滾動處理函數
onHandleScroll = () => {
const { eleFixedTop } = this.state;
//獲取滾動距離
let scroll = document.body.scrollTop + document.documentElement.scrollTop;
//如果窗口滾動的距離 大於 元素距離頁面頂部的距離,則設置元素爲固定定位,實現吸附效果
if (scroll >= (eleFixedTop - 20)) { //+10是爲了吸附效果
this.setState({
fixed: true,
})
} else {
this.setState({
fixed: false,
})
}
}
componentDidMount() {
//獲取組件距離頁面頂部距離
const fixedTop = document.getElementById("overview").offsetTop;
this.setState({
eleFixedTop: fixedTop,
})
//滾動監聽事件
window.onscroll = this.onHandleScroll;
}
render() {
const { data, onSwitchChange } = this.props;
const { fixed } = this.state;
return <div className={style.overview}>
{
// 固定定位脫離文檔流會導致之前的元素被壓住,這裏用一個空的div來撐開
//此div的高度與脫離文檔流的相同
fixed && <div style={{ height: `${document.getElementById('overview').clientHeight}px` }}></div>
}
<div className={`${style.fixed} clearfix`} id="overview" style={fixed ? { position: "fixed", top: "0px", } : { position: "relative" }}>
這裏是要固定的內容,省略。。。
</div>
</div>
}
}
export default MaterialOverview