收藏
回答

自定义组件如何优雅的监听页面的滚动事件?

如题,请各位集思广益,谢谢!

回答关注问题邀请回答
收藏

5 个回答

  • 阿旺
    阿旺
    2021-05-19

    在不了解你的需求的前提下我姑且说一下当时我需要这个需求时的处理方法:因为有的页面是一个长列表,随着分页的数据增多或者业务显示增多,页面会被用户滚动到底部,所以需要就提出了一个 回到顶部的需求(在页面浮窗) 当时这个需求会用在很多长列表页面 所以如果在每个需要的页面去写一段业务逻辑就很冗余,所以考虑到封装成组件,但是组件内又没有监听页面的办法。但是我想到了另外的一种实现途径:在组件内部有一个空的view利用绝对定位使其默认放置在屏幕的最上方,通过wx.createIntersectionObserver 监听这个view滚动超出一屏幕 或者指定距离时 对组件进行显示/隐藏处理。这样一样就抽取了一个公共组件 用在了需要的页面,当然这个组件最好放置在所用页面的最外层。不知是否能帮到你

    2021-05-19
    有用 4
    回复 3
    • ThenMorning
      ThenMorning
      2021-05-25
      谢谢
      2021-05-25
      回复
    • 菜菜驴
      菜菜驴
      2022-02-24
      请问找到优雅的方法了吗?
      2022-02-24
      回复
    • 我的星星
      我的星星
      2022-09-12
      优雅,实在优雅
      2022-09-12
      1
      回复
  • Jhou旭
    Jhou旭
    2021-03-04

    正好我最近也在做类似的案例,先说一下我的做法:

    首先在父页面中使用:onPageScroll()监听滚动的时间,

    然后在父页面定义一个状态,将onPageScroll()事件中获取到的数据setDate给刚定义的状态,

    其次在父页面wxml中传值给子组件

    最后在子组件接收传递过来的数据就可以了。

    当父页面发生滚动的时候触发状态的更新,从而使传递到子组件的数据也回跟着更新,通过这个数据的变动可以得知父组件触发了滚动。

    简单点来说就是:监听父页面的滚动状态,使用数据设置给父页面的状态中(可以是距离页面顶部的距离:e.scrollTop),通过父传子参数,在子组件接收这个参数,并且监听这个参数是否发生了变化即可。

    (下图的是,子组件接收父页面参数的写法,observer是检测参数是否发生变化的事件)。


    我的思路大致是这样,希望能够帮助到你。

    2021-03-04
    有用 1
    回复 10
    • ThenMorning
      ThenMorning
      2021-03-04
      谢谢你的回复,这个思路我想过,现在想要的就是优雅点的
      2021-03-04
      回复
    • 耿霄
      耿霄
      2021-03-04回复ThenMorning
      你的把你的优雅点给个定义,还有应用场景。这样全靠猜
      2021-03-04
      回复
    • ThenMorning
      ThenMorning
      2021-03-04回复耿霄
      对页面来说成本低,对线上影响小,可扩展性高
      2021-03-04
      回复
    • 耿霄
      耿霄
      2021-03-04
      如果官方自定义组件支持就OK了,这样是最优雅的
      2021-03-04
      1
      回复
    • ThenMorning
      ThenMorning
      2021-03-04回复耿霄
      那确实  哈哈哈
      2021-03-04
      回复
    查看更多(5)
  • SimonFungC
    SimonFungC
    2022-09-01

    监听路由复写onPageScroll方法,再把滚动事件广播就可以了。

    // app.js  
    // onLaunch中监听当前路由,并发送事件
    wx.onAppRoute((res) => {
          let pages = getCurrentPages();
          let view = pages[pages.length - 1];
          if (view) {
            // * 被监听页面需要暴露onPageScroll方法
            view.onPageScroll = (e) => {
              // 广播事件(自行封装)
              this.eventBus.$emit({
                  name: "_evt_page_scroll",
                data: e
              })
            };
          }
        })
    


    // custom-component.js
    // 自定义组件监听事件
    app.eventBus.$on({
          name: "_evt_page_scroll",
          tg: this,
          success: (res) => {
            // 监听全局滚动事件
            console.log("_evt_page_scroll:", res);
          }
        })
    


    2022-09-01
    有用
    回复
  • 睡前原谅一切
    睡前原谅一切
    2021-03-04

    做个广播吧。。。

    2021-03-04
    有用
    回复 3
    • ThenMorning
      ThenMorning
      发表于移动端
      2021-03-04
      我说的优雅指的是 把页面滚动监听放到组件内且 对原代码的影响不大
      2021-03-04
      回复
    • 睡前原谅一切
      睡前原谅一切
      2021-03-04回复ThenMorning
      类似于vue的 eventbus
      2021-03-04
      回复
    • 睡前原谅一切
      睡前原谅一切
      2021-03-04回复ThenMorning
      还想再优雅 提个需求,让官方实现
      2021-03-04
      回复
  • 耿霄
    耿霄
    2021-03-04

    1.封装一个BasePage,BasePage 支持 onPageScroll 事情,默认不支持订阅。

    2.页面继承 BasePage,需要监听滚动的就进行订阅。

    相当于每个页面都具备这样的能力,如果需要直接订阅,不需要就不订阅

    2021-03-04
    有用
    回复 4
    • ThenMorning
      ThenMorning
      2021-03-04
      嗯  谢谢回复    确实这样   basepage抽出了监听滚动的工作,但是自定义组件获取页面滚动状态的工作还是没有抽象复用
      2021-03-04
      回复
    • 耿霄
      耿霄
      2021-03-04回复ThenMorning
      这个不是页面维度的滚动了,那建议自定义搞一个scrollview 组件,不用onPageScroll 事情了。需要页面需要用到滚动,都使用 scrollview 组件包一层
      2021-03-04
      回复
    • ThenMorning
      ThenMorning
      发表于移动端
      2021-03-04回复耿霄
      如此的话,成本又太高了,我现在就需要一个小程序的黑魔法😂😂😂
      2021-03-04
      回复
    • 耿霄
      耿霄
      2021-03-04回复ThenMorning
      爱莫能助 哈哈,加油
      2021-03-04
      回复
登录 后发表内容
问题标签