水赤着脚走在潮湿的街上;树叶,像病人般,抱怨那树。 ---巴勃罗·聂鲁达-
![10行代码最简单逻辑「uni-app滚动监听判断用户滑动方向]](https://cdn.frbkw.com/wp-center/uploads/2025/12/20251226101946512.jpg)
序
之前如果我们需要判断用户在页面是向上滑动 还是下滑动需要用到触摸事件;毫无疑问他应该合理的接解决方案,但是一个滑动需要用到3个事件,搞不好还要套一个scroll-view......那真大可不义必
@touchstart="handleTouchStart" <!-- 手指按下时触发 -->
@touchmove="handleTouchMove" <!-- 手指移动时触发(实时) -->
@touchend="handleTouchEnd" <!-- 手指松开时触发 -->
另类思路
都是靠滑动监听,可以直接采用onPageScroll,代码量少;而且对比touchstart监听事件来说,新手更容易操作;10行代码最简单逻辑「uni-app滚动监听判断用户滑动方向
// 监听页面滚动事件
onPageScroll(e) {
this.scrollTop = e.scrollTop;
// 判断滚动方向
if (e.scrollTop != 0) {
let newDirection = '';
// 计算滚动差距,必须大于50才判断为有效滚动
let scrollDiff = Math.abs(this.scrollTop - this.lastScrollTop);
if (scrollDiff > 20) {
if (this.scrollTop > this.lastScrollTop) {
newDirection = 'down'; // 向下滚动
} else if (this.scrollTop < this.lastScrollTop) {
newDirection = 'up'; // 向上滚动
}
}
// 只有当滚动方向发生变化时才更新scrollDirection
if (newDirection && newDirection !== this.scrollDirection) {
this.scrollDirection = newDirection;
console.log('滚动方向', newDirection)
}
} else {
this.scrollDirection = 'up';
}
// 更新上次滚动位置
this.lastScrollTop = this.scrollTop;
// console.log(e.scrollTop)
},
优点
- ✅ 自动管理 :无需手动处理事件绑定和解绑
- ✅ 跨平台兼容 :自动适配小程序、H5、APP
- ✅ 简单可靠 :API稳定,不易出错
缺点:
- ❌ 触发频率固定 :无法自定义节流间隔
- ❌ 功能局限 :只能获取scrollTop,无法获取触摸详情
截图
![10行代码最简单逻辑「uni-app滚动监听判断用户滑动方向]](https://cdn.frbkw.com/wp-center/uploads/2025/12/20251226102306825.png)
![10行代码最简单逻辑「uni-app滚动监听判断用户滑动方向]](https://cdn.frbkw.com/wp-center/uploads/2025/12/20251226102313318.png)
案例
index.vue
<template>
<view class="container">
<view class="status-bar">
<view class="direction-info">
滚动方向: {{ scrollDirection === 'down' ? '⬇️ 向下滑动' : scrollDirection === 'up' ? '⬆️ 向上滑动' : '未滚动' }}
</view>
<view class="position-info">
滚动位置: {{ scrollTop }}px
</view>
</view>
<view class="content">
<view class="section" v-for="(item, index) in 20" :key="index">
<view class="section-title">第 {{ index + 1 }} 个区域</view>
<view class="section-content">
这是第 {{ index + 1 }} 个内容区域,用于演示滚动监听效果。
当前滚动方向:{{ scrollDirection }}
</view>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
scrollTop: 0, // 当前滚动位置
lastScrollTop: 0, // 上次滚动位置
scrollDirection: '' // 滚动方向:'up' 或 'down'
}
},
onLoad() {
},
// 监听页面滚动事件
onPageScroll(e) {
this.scrollTop = e.scrollTop;
// 判断滚动方向
if (e.scrollTop != 0) {
let newDirection = '';
// 计算滚动差距,必须大于50才判断为有效滚动
let scrollDiff = Math.abs(this.scrollTop - this.lastScrollTop);
if (scrollDiff > 20) {
if (this.scrollTop > this.lastScrollTop) {
newDirection = 'down'; // 向下滚动
} else if (this.scrollTop < this.lastScrollTop) {
newDirection = 'up'; // 向上滚动
}
}
// 只有当滚动方向发生变化时才更新scrollDirection
if (newDirection && newDirection !== this.scrollDirection) {
this.scrollDirection = newDirection;
console.log('滚动方向', newDirection)
}
} else {
this.scrollDirection = 'up';
}
// 更新上次滚动位置
this.lastScrollTop = this.scrollTop;
// console.log(e.scrollTop)
},
methods: {
}
}
</script>
<style>
.container {
min-height: 100vh;
background-color: #f5f5f5;
}
.status-bar {
position: fixed;
top: 0;
left: 0;
right: 0;
background-color: #007AFF;
color: white;
padding: 20rpx;
z-index: 1000;
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.1);
}
.direction-info {
font-size: 32rpx;
font-weight: bold;
margin-bottom: 10rpx;
}
.position-info {
font-size: 28rpx;
opacity: 0.9;
}
.content {
padding-top: 120rpx;
padding-bottom: 40rpx;
}
.section {
margin: 20rpx;
padding: 40rpx;
background-color: white;
border-radius: 16rpx;
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.05);
}
.section-title {
font-size: 36rpx;
font-weight: bold;
color: #333;
margin-bottom: 20rpx;
}
.section-content {
font-size: 28rpx;
color: #666;
line-height: 1.6;
}
</style>