hold-scroll

1.0.2 • Public • Published

保存组件中滚动区域的位置

需求
一个keepalive的组件,页面中有一个滚动区域(滚动区域渲染了列表),我们需要从此页面跳到其他页面上,然后再回到这个页面时,滚动条任然在先前的位置
问题
缓存组件会变成js对象被存储,此时他的滚动条高度信息消失,js的路由守卫配置方法只能设置页面滚动条,
思路
给滚动列表的项唯一标识符,记录离滚动视口最近的哪一项与滚动视口的相对高度top,以及这一项的id属性,回到keepalive页面时,根据top和id计算滚动区域应该滚动的高度

使用方式及注意点

  • 容器形式

    跟betterscroll差不多

    • itemsContainer 滚动视口
    • itemsList 滚动内容区
    • item滚动区中的元素必须有id属性且唯一
     <div class="show" @scroll="getmin()" ref="itemsContainer">
            <div class="show-warpper"  ref="itemsList">
              <div class="item" :id ="item.id" :style="`background-color:${item.color};height:${item.height}px`" v-for="(item) in items" :key="item.id">
              </div>
            </div>
        </div>
  • 存储高度信息的时机

    视情况而定,宗旨为可能使页面变化的一切因素,本例中是滚动事件,列表数据源变化

  • 设置高度信息的时机

    activated生命周期钩子(重新激活组件时)

使用方式

引入

npm install hold-scroll

拿到滚动视口,滚动内容区(通过ref)
<div class="show" ref="itemsContainer">
        <div class="show-warpper"  ref="itemsList">

设置seesionStorage的key,调用核心方法,保存,设置滚动高度

方法编写

    //获取高度
    getmin(){
      
        const itemsContainer = this.$refs.itemsContainer
        const itemswrapper = this.$refs.itemsList
        holdScroll.saveHInfo(itemsContainer,itemswrapper,'list')
        
    },

    //设置高度
    setmin(){
      const itemsContainer = this.$refs.itemsContainer
      const itemswrapper = this.$refs.itemsList
      holdScroll.setHInfo(itemsContainer,itemswrapper,'list')

    }

保存高度

  • 滚动(设置给滚动视口)
<div class="show" @scroll="getmin()" ref="itemsContainer">
  • 数据更新
 updated(){
    this.$nextTick(()=>{
      this.getmin()
    })
  },

设置高度

  • 组件被激活
  //设置高度
  activated(){
    this.setmin()
  },
核心方法
        /**
         * itemsContainer 是滚动区域,固定高度,overflow:scroll
         * itemswrapper 是滚动内容容器,用来包装容器内的元素
         * 容器的元素是item,方法中不用写这个参数,但是在DOM结构中需要体现
         * 
         * @params {HTMLElement} itemsContainer 
         * @params {HTMLElement} itemswrapper 
         * @params {String} key 页面信息存储到sessionStorage 的唯一标识
         *  id 具有唯一标识的item元素的id,将要保存到sessionStorage的名称(key)
         *  top 某个特殊元素顶部到滚动区域顶部的距离,将要保存到sessionStorage的名称(key)
         * 
         */
        function saveHInfo(itemsContainer,itemswrapper,key){
            const offsetTop = itemsContainer.getBoundingClientRect().top
            const itemCollections = itemswrapper.children
            let items = Array.from(itemCollections)
            let minId
            let minTop
            if(itemsContainer.getBoundingClientRect().width == 0){
                return ;
            }
            items.forEach(item=>{
                //高度
                const top = item.getBoundingClientRect().top-offsetTop
                if(top>=0){
                    if(!minId){
                    minId = item.id
                    minTop = top
                    }else if(top<minTop){
                        minTop = top
                        minId = item.id
                    }
                }
            })

            sessionStorage.setItem(key+'_id',minId)
            sessionStorage.setItem(key+'top',minTop)
    }
    // 设置高度
    function setHInfo(itemsContainer,itemswrapper,key){

        const itemCollections = itemswrapper.children
        const minId = sessionStorage.getItem(key+'_id')
        const minTop = sessionStorage.getItem(key+'top')

        if(!minId) return
        let topHeight = 0
        let items = Array.from(itemCollections);

        items.some(item=>{
            if(item.id == minId){
                topHeight+=parseInt(getComputedStyle(item).marginTop)
                return true
            }
            topHeight+=
            parseInt(getComputedStyle(item).marginTop)
            +
            parseInt(getComputedStyle(item).marginBottom)
            +
            item.offsetHeight

        })
    
        itemsContainer.scrollTop =  topHeight-minTop
       
    }

Readme

Keywords

Package Sidebar

Install

npm i hold-scroll

Weekly Downloads

2

Version

1.0.2

License

ISC

Unpacked Size

8.52 kB

Total Files

3

Last publish

Collaborators

  • xiaoadong