zoukankan      html  css  js  c++  java
  • JS实现滚动区域触底事件

    效果

    贴上效果展示:

    实现思路

    样式方面不多赘述,滚动区域是给固定高度,设置 overflow-y: auto 来实现。

    接下来看看js方面的实现,其实也很简单,触发的条件是: 可视高度 + 滚动距离 >= 实际高度 。例子我会使用vue来实现,和原生实现是一样的。

    • 可视高度(offsetHeight):通过 domoffsetHeight 获得,表示区域固定的高度。这里我推荐通过 getBoundingClientRect() 来获取高度,因为使用前者会引起浏览器回流,造成一些性能问题。
    • 滚动高度(scrollTop):滚动事件中通过 e.target.scrollTop 获取,表示滚动条距离顶部的px
    • 实际高度(scrollHeight):通过 domscrollHeight 获得,表示区域内所有内容的高度(包括滚动距离),也就是实际高度

    基础实现

    onScroll(e) {
        let scrollTop = e.target.scrollTop
        let scrollHeight = e.target.scrollHeight
        let offsetHeight = Math.ceil(e.target.getBoundingClientRect().height)
        let currentHeight = scrollTop + offsetHeight
        if (currentHeight >= scrollHeight) {
            console.log('触底')
        }
    }
    

    so easy~

    加点细节

    加点细节,现在我们希望是离底部一定距离就触发事件,而不是等到完全触底。如果你做过小程序,这和onReachBottom差不多的意思。

    声明一个离底部的距离变量reachBottomDistance

    这时候触发条件:可视高度 + 滚动距离 + reachBottomDistance >= 实际高度

    export default {
      data(){
        return {
          reachBottomDistance: 100
        }
      },
      methods: {
        onScroll(e) {
            let scrollTop = e.target.scrollTop
            let scrollHeight = e.target.scrollHeight
            let offsetHeight = Math.ceil(e.target.getBoundingClientRect().height)
            let currentHeight = scrollTop + offsetHeight + this.reachBottomDistance
            if (currentHeight >= scrollHeight) {
                console.log('触底')
            }
        }
      }
    }
    

    在距离底部100px时成功触发事件,但由于100px往下的区域是符合条件的,会导致一直触发,这不是我们想要的。

    接下来做一些处理,让其进入后只触发一次:

    export default {
      data(){
        return {
          isReachBottom: false,
          reachBottomDistance: 100
        }
      },
      methods: {
        onScroll(e) {
            let scrollTop = e.target.scrollTop
            let scrollHeight = e.target.scrollHeight
            let offsetHeight = Math.ceil(e.target.getBoundingClientRect().height)
            let currentHeight = scrollTop + offsetHeight + this.reachBottomDistance
    
            if(currentHeight < scrollHeight && this.isReachBottom){
              this.isReachBottom = false
            }
            if(this.isReachBottom){
              return
            }
            if (currentHeight >= scrollHeight) {
              this.isReachBottom = true
              console.log('触底')
            }
        }
      }
    }
    

    优化

    实时去获取位置信息稍微会损耗性能,我们应该把不变的缓存起来,只实时获取可变的部分

    export default {
      data(){
        return {
          isReachBottom: false,
          reachBottomDistance: 100
          scrollHeight: 0,
          offsetHeight: 0,
        }
      },
      mounted(){
        // 页面加载完成后  将高度存储起来
        let dom = document.querySelector('.comment-area .comment-list')
        this.scrollHeight = dom.scrollHeight
        this.offsetHeight = Math.ceil(dom.getBoundingClientRect().height)
      },
      methods: {
        onScroll(e) {
            let scrollTop = e.target.scrollTop
            let currentHeight = scrollTop + this.offsetHeight + this.reachBottomDistance
    
            if(currentHeight < this.scrollHeight && this.isReachBottom){
              this.isReachBottom = false
            }
            if(this.isReachBottom){
              return
            }
            if (currentHeight >= this.scrollHeight) {
              this.isReachBottom = true
              console.log('触底')
            }
        }
      }
    }
    

    实现到这里就告一段落,如果你有更好的思路和值得改进的地方,欢迎交流~

  • 相关阅读:
    Configure JSON.NET to ignore DataContract/DataMember attributes
    Visual Studio 独立 Shell 下载
    Xamarin.Forms 自定义 TapGestureRecognizer 附加属性
    Xamarin 自定义 ToolbarItem 溢出菜单实现(Popover/Popup) 弹出下拉效果
    xamarin.forms 动态条件更换数据模板
    Xamarin.Forms FlexLayout 布局扩展+ 模板扩展+弹性换行
    Xamarin.Forms 开发资源集合
    Xamarin Forms Api请求开源框架Refit
    Xamarin Forms error MSB6006: “java.exe”已退出,代码为 2 解决办法
    Xamarin.Forms 未能找到路径“x:platforms”的一部分
  • 原文地址:https://www.cnblogs.com/chanwahfung/p/12540114.html
Copyright © 2011-2022 走看看