如何在侧边栏中收听滚动事件 [Bootstrap Vue]

How can I listen to the scroll event in a sidebar [Bootstrap Vue]

我正在使用 BootstrapVue 中的 Sidebar 组件为我的应用程序呈现导航。

例如,我的导航中有 30 个菜单项,因此边栏中的内容会垂直滚动。我想将滚动事件绑定到动态 add/remove 一些 类.

我已尝试创建自定义滚动指令:

Vue.directive('scroll', {
    inserted: function(el, binding) {
        console.log('el', el);
        let f = function(evt) {
            if (binding.value(evt, el)) {
                window.removeEventListener('scroll', f);
            }
        };

        window.addEventListener('scroll', f);
    }
});

...然后将其注册到我的 vue 文件中的组件:

<b-sidebar
   v-scroll="handleScroll"
   title="Menu"
   shadow="lg"
   backdrop
   @change="$emit('sidebar-change')"


...

handleScroll() {
      console.log('handleScroll');
},

指令被正确拾取,但我的 handleScroll 方法在主体滚动时触发,而不是侧边栏。

在我的指令中,我正在记录以查看它认为正在使用的元素:

<div tabindex="-1" class="b-sidebar-outer">...</div>

由于 Bootstrap 正在为叠加层动态创建标记,这是父元素——仔细观察,我相信我需要将我的指令附加到此:

<div class="b-sidebar-body">...</div>

那是看起来在滚动的 <div>。但是,由于它是在运行时生成的,我不知道如何挂钩它。

我也试过在组件上使用 @native.scroll="myMethod"...也不走运。

如何在我的侧边栏组件中侦听滚动事件?感谢您的任何建议!

您需要检查事件的目标是否是侧边栏,如果是则只执行您的函数。

您的 scroll 侦听器在主 window 上触发,因为指令将事件侦听器附加到 window,而不是元素。

要监听 b-sidebar 内容的滚动事件,监听器应该位于 b-sidebar 的默认槽内的元素上(而不是 b-sidebar 本身)。

  1. 将包装器 div 放入 b-sidebar 的默认插槽中,并设置样式以启用滚动:

    <template>
      <b-sidebar>
        <div class="wrapper">
          <!-- your actual contents here -->
        </div>
      </b-sidebar>
    </template>
    
    <style>
    .wrapper {
      overflow: auto;
      height: 100%;
    }
    </style>
    
  2. 在包装器上添加自定义 v-scroll 指令 div:

    <div class="wrapper" v-scroll="handleScroll">
    
  3. 更新自定义指令以将绑定值添加为给定元素的 scroll 事件的事件侦听器:

    Vue.directive('scroll', (el, binding) => {
      let f = (evt) => {
        if (binding.value(evt, el)) {
          el.removeEventListener('scroll', f)
        }
      }
    
      el.addEventListener('scroll', f)
    })
    

demo