react記錄頁面的滾動條位置

多芒小丸子發表於2018-08-24

從資料較多的列表頁進入詳情頁返回時,列表頁恢復原來的狀態。

需求:

從一個橫向縱向都有滾動條的列表頁進入詳情頁,返回時列表頁的活動條恢復到之前到位置。

難點:

1.列表用的是antd的table元件,滾動條是這個table元件的,瀏覽器返回時自身可以記錄頁面即document的滾動條,但不能記錄某一個元素的滾動條。

2.資料載入,每次進去列表頁時資料都會重新載入,列表的初始值都為空,表頭也需要動態載入,所以返回頁面時,整個列表是沒有高度和寬度的,所以即使設一個初始的滾動條位置也不會生效。

解決方案:

1. 設定列表資料初值

在離開列表頁時將載入列表相關的資料儲存到本地,或者放到redux裡,返回頁面時可以直接取值,列表不會沒有寬高。在列表頁初始化時即constructor 時就可以將存下來的資料取出賦值。

2.設定列表滾動條位置初值

審查列表頁渲染以後的節點,找到滾動條所對應的元素,並將其作為目標元素操作dom。

離開頁面時記錄滾動條的位置,在生命週期didmount 裡操作dom設定滾動條的初始位置。

離開頁面時可以是componentWillUnmount或者是頁面跳轉前。

操作dom時用原生js的方法和ReactDom得ReactDom.FindDOMNode方法結合。

部分程式碼:

componentDidMount() {
    var Btn = document.getElementsByClassName('ant-table-body')[0]
    const scrollLeft = localDb.get('scrollLeft') || 0;
    const scrollTop = localDb.get('scrollTop') || 0;
    // 設定滾動條的位置
    ReactDOM.findDOMNode(Btn).scrollTo(scrollLeft, scrollTop);
    let params = {}
    const { initDate } = this.state
    params.beginDate = initDate[0]
    params.endDate = initDate[1]
    this.loadData(params)
}
componentWillUnmount() {
   // 通過審查元素找到滾動條的盒子元素類
    const scrollLeft = document.getElementsByClassName('ant-table-body')[0].scrollLeft;
    const scrollTop = document.getElementsByClassName('ant-table-body')[0].scrollTop;
    const {
      wid,
      checkedUUids,
      org,
      data,
      type
    } = this.state
    localDb.set('scrollLeft', scrollLeft);
    localDb.set('scrollTop', scrollTop);
}
複製程式碼

後記

今天一個朋友問我要怎麼react後退不重新整理時,我告訴他了我的這種實現方式,不難但是複雜。一直以來用vue開發的他,發出了這麼一聲感嘆,然後告訴我vue只要在元件外包一層keep-alive就可以記錄元件的狀態了,呃真的真的是灰常簡單啊。

相關文章