关于阻止scroll()事件多次执行的一个小方法

本文介绍了一种使用scroll事件的防抖方法,通过条件判断加延迟执行的方式避免scroll事件被频繁触发导致的性能问题。该方法通过设置一个布尔型变量,在scroll事件触发时进行检查,如果该变量为真,则执行函数并将其设为假,之后通过setTimeout恢复变量状态。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近写一个小demo,需要用到scroll事件,可又不希望它多次执行,网上搜了挺多方法,有一个虽然有点小bug但也挺好用,贴出来与大家分享,直接上栗子:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <link>
</head>
<body>

</body>
<script>
    //创建一些p标签,使网页可以滚动
    for(var i=0;i<20;i++){
        var p=document.createElement("p");
        var t=document.createTextNode("滚动条");
        p.appendChild(t);
        document.body.appendChild(p);
    }
    //下面是主要的执行代码,整体思路就是:条件判断+延迟执行。在事件执行之初,复活变量,事件执行完毕后 杀死变量
    var tur = true;
    window.onscroll = function (){
        if(tur){
            setTimeout(scro,500); 
            tur = false; //杀死变量
        }else{

        } 
    };
    //需要执行的函数
    function scro(){
        alert(1);
        tur = true;//复活变量
    };
</script>
</html>
<think>我们正在处理一个关于uni-app中onReachBottom生命周期函数只执行一次的问题。根据引用[1]和引用[4]的信息,我们可以知道onReachBottom是用于监听页面上拉触底事件的生命周期函数,但有时可能只触发一次就不再触发。 可能的原因和解决方案: 1. 页面内容高度不够:如果页面内容没有超过一屏,那么无法触发上拉触底事件。需要确保内容足够长,使得页面可以滚动。 2. 在onReachBottom中加载数据后,没有将新数据追加到页面数据中,导致页面高度没有增加,因此无法再次触发。或者虽然追加了数据,但新数据没有撑开页面(例如,新数据的高度不足以超过当前屏幕)。 3. 在onReachBottom中,可能设置了某些状态(比如加载完毕标志)阻止了再次触发,需要检查逻辑。 4. 页面结构问题:如果页面中使用了scroll-view等滚动容器,那么页面的滚动事件会被scroll-view接管,导致页面级别的onReachBottom无法触发。此时应该使用scroll-view的滚动到底部事件代替。 5. 配置问题:在pages.json中,需要设置onReachBottomDistance(单位px)来调整触发距离,确保这个距离设置合理。 根据引用[1]中的示例,我们在pages.json中设置onReachBottomDistance,并在页面中编写onReachBottom函数。同时,引用[4]提到enablePullDownRefresh的设置,但这与上拉触底无关。 解决方案步骤: 1. 检查页面内容高度:确保页面内容超过一屏,可以滚动。 2. 检查pages.json配置:在对应页面的style中设置onReachBottomDistance(如100px)。 3. 检查页面结构:避免使用scroll-view等滚动容器,如果必须使用,则改用scroll-view的@scrolltolower事件。 4. 在onReachBottom函数中,正确加载数据并追加到页面数据数组中,同时确保新数据会使得页面高度增加(比如每次加载多条数据)。 5. 确保没有在加载过程中设置状态(如hasMore=false)而阻止了后续触发,通常我们会有一个变量(如isLoading, hasMore)来控制是否允许加载,在每次加载完成后重置isLoading,当没有更多数据时设置hasMore为false并不再触发加载。 示例代码(参考引用[1]): 在pages.json中: ```json { "path": "pages/test/test", "style": { "navigationBarTitleText": "测试页面", "onReachBottomDistance": 100 // 设置触底距离为100px } } ``` 在页面中: ```javascript export default { data() { return { list: [], // 数据列表 page: 1, // 当前页码 hasMore: true, // 是否还有更多数据 isLoading: false // 是否正在加载 } }, onLoad() { this.loadData() }, methods: { loadData() { if (!this.hasMore || this.isLoading) return this.isLoading = true // 模拟请求数据 setTimeout(() => { // 假设每次请求10条数据 const newData = Array.from({ length: 10 }, (_, i) => ({ id: this.page * 10 + i, name: `Item ${this.page * 10 + i}` })) this.list = [...this.list, ...newData] this.page++ // 假设数据总数是50条,这里判断是否还有更多数据 if (this.page > 5) { this.hasMore = false } this.isLoading = false }, 1000) } }, onReachBottom() { // 触底时加载更多数据 console.log('触底事件触发') this.loadData() } } ``` 如果使用了scroll-view,则改为: 在页面模板中: ```html <scroll-view scroll-y="true" style="height: 100vh;" @scrolltolower="loadMore"> <!-- 内容 --> </scroll-view> ``` 注意:使用scroll-view时,需要设置一个固定的高度(例如100vh),并且不再使用onReachBottom生命周期函数,而是使用scroll-view的@scrolltolower事件。 如果按照上述步骤仍然无法解决,请检查是否有其他因素(如页面样式导致高度计算错误,或者页面中有多个滚动区域等)。 相关问题: 1. uni-app中如何实现下拉刷新? 2. uni-app中scroll-view组件的使用方法有哪些? 3. 如何优化uni-app中的长列表滚动性能?</think>### uni-app onReachBottom 只执行一次问题解决方案 在 uni-app 中,`onReachBottom` 生命周期函数只触发一次通常由以下原因导致: #### 常见原因及解决方案 1. **页面内容高度不足** - 问题:页面内容未超过屏幕高度,无法触发滚动 - 解决: ```javascript // 在 onLoad 中主动添加初始数据 onLoad() { this.list = Array(20).fill().map((_,i) => ({id: i})) // 确保内容超过一屏 } ``` 2. **未正确追加新数据** - 问题:新数据未更新到页面导致高度不变 - 解决: ```javascript onReachBottom() { const newData = Array(5).fill().map((_,i) => ({id: this.list.length + i})) this.list = [...this.list, ...newData] // ✅ 正确追加数据 } ``` 3. **pages.json 配置缺失**(关键!) - 问题:未设置触发距离 - 解决: ```json // pages.json { "path": "pages/yourPage", "style": { "onReachBottomDistance": 50, // 必须设置!单位px "enablePullDownRefresh": true // 建议同时开启下拉刷新 } } ``` 4. **页面结构冲突** - 问题:使用 `scroll-view` 接管了页面滚动 - 解决: ```html <!-- 错误示例 --> <scroll-view scroll-y> <!-- 会屏蔽页面级滚动事件 --> <!-- 正确:移除scroll-view改用普通view --> <view> <!-- 长列表内容 --> </view> ``` 5. **加载状态未重置** - 问题:`loading` 状态锁阻止二次触发 - 解决: ```javascript data() { return { loading: false } }, onReachBottom() { if (this.loading) return // 防止重复触发 this.loading = true // 模拟请求 setTimeout(() => { this.list.push(...newData) this.loading = false // ✅ 关键:重置状态 }, 500) } ``` #### 完整示例代码 ```javascript // 页面脚本 export default { data() { return { list: [], loading: false, page: 1 } }, onLoad() { // 初始化数据 this.list = Array(15).fill().map((_,i) => ({id: i+1})) }, onReachBottom() { if (this.loading) return this.loading = true uni.showLoading({ title: '加载中' }) // 模拟API请求 setTimeout(() => { const newData = Array(5).fill().map((_,i) => ({ id: this.list.length + i + 1 })) this.list = [...this.list, ...newData] this.page++ this.loading = false uni.hideLoading() }, 1000) } } ``` ```json // pages.json 关键配置 { "pages": [ { "path": "pages/yourPage", "style": { "navigationBarTitleText": "分页示例", "onReachBottomDistance": 50, // 触发距离(必须) "enablePullDownRefresh": true // 推荐开启 } } ] } ``` > **注意**:若使用自定义导航栏(`"navigationStyle": "custom"`),需确保页面内容从屏幕顶部开始布局,否则可能影响滚动区域计算[^1]。 --- ### 相关问题 1. **如何优化 uni-app 长列表性能避免卡顿?** 2. **uni-app 中 scroll-view 和页面滚动应该如何选择?** 3. **如何实现 uni-app 的下拉刷新功能?** 4. **uni-app 跨端开发如何处理平台差异?** [^1]: uni-app 官方文档 - 页面生命周期 [^2]: uni-app 性能优化指南 [^3]: DCloud 技术社区 - 滚动区域计算原理
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值