JS实现滚动区域触底事件
效果
贴上效果展示:

实现思路
样式方面不多赘述,滚动区域是给固定高度,设置 overflow-y: auto 来实现。
接下来看看js方面的实现,其实也很简单,触发的条件是: 可视高度 + 滚动距离 >= 实际高度 。例子我会使用vue来实现,和原生实现是一样的。
- 可视高度(offsetHeight):通过
dom的offsetHeight获得,表示区域固定的高度。这里我推荐通过getBoundingClientRect()来获取高度,因为使用前者会引起浏览器回流,造成一些性能问题。 - 滚动高度(scrollTop):滚动事件中通过
e.target.scrollTop获取,表示滚动条距离顶部的px - 实际高度(scrollHeight):通过
dom的scrollHeight获得,表示区域内所有内容的高度(包括滚动距离),也就是实际高度
基础实现
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实现滚动区域触底事件的更多相关文章
- (转)js的左右滑动触屏事件
原文:http://blog.sina.com.cn/s/blog_6a0a183f0100zsfk.html (2012-01-20 08:55:53) 转载▼ 标签: 移动设备 触屏事件 杂谈 分 ...
- js 滚动条滚动到底部触发事件
一.前言 在开发项目时,常常需要展示大量数据.如果全部显示出来,数据相对少时,看不出来什么不同,如果数据很多时,一次请求全部显示,这就相当可怕了. 面对这种问题,PC里使用了分页效果,将数据分成一页页 ...
- js滚动条滚动到底部触发事件
$("#contain").scroll(function(){ var $this =$(this), viewH =$(this).height(),//可见高度 conten ...
- js触屏事件
js的左右滑动触屏事件,主要有三个事件:touchstart,touchmove,touchend.这三个事件最重要的属性是 pageX和 pageY,表示X,Y坐标. touchstart在触摸开始 ...
- 前端 | 页面触底自动加载 Vue 组件
不管是 web 端还是移动端,信息流都是现在很流行的信息展示方式.信息流经常搭配自动加载一起使用以获得更好的使用体验. 最近在使用 Vue 开发过程中也遇到了首页信息流自动加载的需求.大致了解了一下几 ...
- el-select实现下拉框触底加载更多
当下拉框需要展示的数据有很多时,几千甚至上万条,一次性全部请求回来再按照特定格式比如 id-name 去处理数据的话,不论是从接口还是前端,这个性能都不是很好,会造成下拉框初次打开时响应很慢,影响用户 ...
- 小程序上拉触底&下拉加载
data: { pageNo: 1,//当前页 pageSize: 10,//每页条数 count:'',//总条数 orderList: [], }, onLoad: function () { v ...
- js滚动事件实现滚动触底加载
移动端触底加载时前端开发过程中常用功能,主要是通过三个值的大小来进行判断: 首先介绍jquery的写法,代码如下: $(window).scroll(function(){ var windowH=$ ...
- vue+hammer.js完美实现长按、左滑,右滑等触控事件
移动端使用手指直接操作的方式大受用户欢迎,这其中就包括了单点.多点.长按.双击等方式. 这么多触控事件,如果开发者自己实现,会浪费大量的时间和精力,快来看看 hammer.js 让我们轻松了多少吧. ...
随机推荐
- 如果你的unordered_map头文件报错请看这里
请将include<unordered_map>头文件换成下面代码 #if(__cplusplus == 201103L) #include <unordered_map> # ...
- btrace简单使用
基本安装 在github上btrace项目的release下 下载最新的btracehttps://github.com/btraceio/btrace/releases 解压完后,将btrace的b ...
- 850. Dijkstra求最短路 II
给定一个n个点m条边的有向图,图中可能存在重边和自环,所有边权均为正值. 请你求出1号点到n号点的最短距离,如果无法从1号点走到n号点,则输出-1. 输入格式 第一行包含整数n和m. 接下来m行每行包 ...
- Acwing 843. n-皇后问题
n-皇后问题是指将 n 个皇后放在 n∗n 的国际象棋棋盘上,使得皇后不能相互攻击到,即任意两个皇后都不能处于同一行.同一列或同一斜线上. 现在给定整数n,请你输出所有的满足条件的棋子摆法. 输入格式 ...
- Struts2获取request的几种方式汇总
Struts2获取request三种方法 struts2里面有三种方法可以获取request,最好使用ServletRequestAware接口通过IOC机制注入Request对象. 在Action中 ...
- Python 列表[::-1]翻转
b = a[i:j:s]: i为起始索引(缺省为0), j为结束索引(不包括,缺省为len(a)), s为步进(缺省为1). 所以a[i:j:1]相当于a[i:j]. 当s<0时: i缺省时,默 ...
- Mysql SQL Mode简介
MySQL服务器能够工作在不同的SQL模式下,并能针对不同的客户端以不同的方式应用这些模式.这样,应用程序就能对服务器操作进行量身定制以满足自己的需求.这类模式定义了MySQL应支持的SQL语法,以及 ...
- Nginx之常用基本配置(二)
上一篇我们把nginx的主配置文件结构大概介绍了下,全局配置段比较常用的指令说了一下,http配置段关于http服务器配置指令介绍了下,以及有几个调优的指令,server_name的匹配机制,错误页面 ...
- USB小白学习之路(7) FPGA Communication with PC by CY7C68013,TD_init()解析
注:这个TD_Init()只对EP6进行了配置,将其配置成为Bluk_In端口,而没有对EP2进行配置.这篇文章直接把寄存器的图片贴上来了,看起来比较杂.感兴趣的可以看下一篇文章,是转自CSDN,对E ...
- 压力测试(四)-Mysql数据库压测实操
1.Jmeter压测实战之JDBC request压测Mysql讲解 简介:讲解jdbc压测mysql相关准备工作,jar包添加,配置讲解 1.Thread Group -> add -> ...