评论
10行代码最简单逻辑「uni-app滚动监听判断用户滑动方向]

10行代码最简单逻辑「uni-app滚动监听判断用户滑动方向]

水赤着脚走在潮湿的街上;树叶,像病人般,抱怨那树。 ---巴勃罗·聂鲁达-

10行代码最简单逻辑「uni-app滚动监听判断用户滑动方向]

之前如果我们需要判断用户在页面是向上滑动 还是下滑动需要用到触摸事件;毫无疑问他应该合理的接解决方案,但是一个滑动需要用到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滚动监听判断用户滑动方向]
10行代码最简单逻辑「uni-app滚动监听判断用户滑动方向]

案例

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>