效果

贴上效果展示:

实现思路

样式方面不多赘述,滚动区域是给固定高度,设置 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('触底')
}
}
}
}

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

JS实现滚动区域触底事件的更多相关文章

  1. (转)js的左右滑动触屏事件

    原文:http://blog.sina.com.cn/s/blog_6a0a183f0100zsfk.html (2012-01-20 08:55:53) 转载▼ 标签: 移动设备 触屏事件 杂谈 分 ...

  2. js 滚动条滚动到底部触发事件

    一.前言 在开发项目时,常常需要展示大量数据.如果全部显示出来,数据相对少时,看不出来什么不同,如果数据很多时,一次请求全部显示,这就相当可怕了. 面对这种问题,PC里使用了分页效果,将数据分成一页页 ...

  3. js滚动条滚动到底部触发事件

    $("#contain").scroll(function(){ var $this =$(this), viewH =$(this).height(),//可见高度 conten ...

  4. js触屏事件

    js的左右滑动触屏事件,主要有三个事件:touchstart,touchmove,touchend.这三个事件最重要的属性是 pageX和 pageY,表示X,Y坐标. touchstart在触摸开始 ...

  5. 前端 | 页面触底自动加载 Vue 组件

    不管是 web 端还是移动端,信息流都是现在很流行的信息展示方式.信息流经常搭配自动加载一起使用以获得更好的使用体验. 最近在使用 Vue 开发过程中也遇到了首页信息流自动加载的需求.大致了解了一下几 ...

  6. el-select实现下拉框触底加载更多

    当下拉框需要展示的数据有很多时,几千甚至上万条,一次性全部请求回来再按照特定格式比如 id-name 去处理数据的话,不论是从接口还是前端,这个性能都不是很好,会造成下拉框初次打开时响应很慢,影响用户 ...

  7. 小程序上拉触底&下拉加载

    data: { pageNo: 1,//当前页 pageSize: 10,//每页条数 count:'',//总条数 orderList: [], }, onLoad: function () { v ...

  8. js滚动事件实现滚动触底加载

    移动端触底加载时前端开发过程中常用功能,主要是通过三个值的大小来进行判断: 首先介绍jquery的写法,代码如下: $(window).scroll(function(){ var windowH=$ ...

  9. vue+hammer.js完美实现长按、左滑,右滑等触控事件

    移动端使用手指直接操作的方式大受用户欢迎,这其中就包括了单点.多点.长按.双击等方式. 这么多触控事件,如果开发者自己实现,会浪费大量的时间和精力,快来看看 hammer.js 让我们轻松了多少吧. ...

随机推荐

  1. Jmeter之CSV文件读取

    注意execl表生成的CSV文件的文件编码是GB2312和分隔符就好了

  2. C++ 部分STL

    map map可以理解为一个数组(但实质上并不是,只是方便理解),我们一般的数组不管定义成什么类型他的下标都是整型(int),map和这些数组的区别是他的下标可以是其他类型,由自己定义.map的创建. ...

  3. <luogu1347>排序

    本来打算当打了个拓扑的板子 后来发现并不只是个板子 差不多 管他呢 #include<cstdio> #include<cstring> #include<iostrea ...

  4. 吴裕雄--天生自然 python语言数据分析:开普勒系外行星搜索结果分析

    import pandas as pd pd.DataFrame({'Yes': [50, 21], 'No': [131, 2]}) pd.DataFrame({'Bob': ['I liked i ...

  5. Choway Blog

    choway 2018-12-11 09:23:46 JavaJVM Java 虚拟机(JVM)在执行 Java 程序时会把它管理的内存划分为多个不同的数据区域.这些区域各有用途,以及创建和销毁的时间 ...

  6. 探索Kinect的更多可能——亲历第十九届机器人世界杯RoboCup

    作者:微软亚洲研究院资深项目经理 吴国斌 2015年7月19日,第十九届RoboCup机器人世界杯足球赛,在中国合肥隆重开幕.来自全球七十六个国家和地区的一百余支代表队参加了决赛,他们优秀的作品给观众 ...

  7. [Golang]字符串拼接方式的性能分析

    本文100%由本人(Haoxiang Ma)原创,如需转载请注明出处. 本文写于2019/02/16,基于Go 1.11.至于其他版本的Go SDK,如有出入请自行查阅其他资料. Overview 写 ...

  8. rbenv、fish 與 VSCode 設置之路

    在最新的 VSCode 1.3.1 版裡,Integrated Terminal 變得更加好用,但由於上游套件 xterm.js 的緣故,zsh 還是有無法捲動的問題.不過作為一個 Rails 開發者 ...

  9. tfgan折腾笔记(一):核心功能简要概述

    tfgan是什么? tfgan是tensorflow团队开发出的一个专门用于训练各种GAN的轻量级库,它是基于tensorflow开发的,所以兼容于tensorflow.在tensorflow1.x版 ...

  10. JavaScript实现队列结构(Queue)

    JavaScript实现队列结构(Queue) 一.队列简介 队列是是一种受限的线性表,特点为先进先出(FIFO:first in first out). 受限之处在于它只允许在表的前端(front) ...