vue 写个内容自动滚动的自定义指令 v-auto-scroll ,鼠标移入停止滚动,移出继续滚动

在大屏或者某些不常使用鼠标交互的页面,数据在定时刷新,如果有个列表数据过多,需要数据自己滚动展示。这里写个通用指令,需要的地方加上即可,轻量。

功能

若容器有滚动条则开启自动滚动,鼠标移入时停止,鼠标移除时继续滚动,可设置自动滚动的动画延迟多久开始启动。目前只支持y方向的,x方向自行扩展,懒得写,加起来也简单。

代码

/**
 * author: yf
 * date: 20241219
 * 列表自动滚动 - 目前只支持 y方向,暂时没有x方向的需求
 * 功能:
 * 若容器有滚动条则开启自动滚动,鼠标移入时停止,鼠标移除时继续滚动
 * 使用方式:
 * 方式一:在滚动节点上使用默认配置
           v-auto-scroll
 * 方式二:完整配置
           v-auto-scroll = {
              targetSelector:  .el-table__body-wrapper , // 当前指令挂载节点内部的滚动盒子,使用 el.querySelector(targetSelector) 查找,节点不存在则使用 el 节点
              delayTime: 1000, // 自动滚动开启的延迟时间,单位 ms
              speed: 2, // 自动滚动速度,值越小滚动速度越快,最小速度为 1
              interval: 1 // 每次自动滚动时移动的距离,单位px - 注意:必须是正整数
           }
 */
Vue.directive( auto-scroll , {
  inserted: function (el, binding) {
    // console.log(el, binding, vnode);

    // 获取配置参数
    let {
      targetSelector =   ,
      delayTime = 1000, // 自动滚动开启的延迟时间,单位 ms
      speed = 4.5, // 自动滚动速度,值越小滚动速度越快,最小速度为 1
      interval = 1 // 每次自动滚动时移动的距离,单位px - 注意:必须是正整数
    } = binding.value || {};

    // 正整数处理
    interval = Math.abs(Math.ceil(interval));

    el._customData = {}; // 需要移除的
    let disabledScroll = false; // 禁止滚动
    let delayTimeSum = 0; // 累计时间,用于判断是否达到延迟时间

    // 滚动元素
    let scrollTarget = targetSelector ? el.querySelector(targetSelector) :   ;
    scrollTarget = scrollTarget || el;
    if (!scrollTarget) return;
    let touchBottom = scrollTarget.scrollHeight - scrollTarget.scrollTop <= scrollTarget.clientHeight // 是否触底

    // 事件处理
    let customEvent = {
      mouseover: function () {
        disabledScroll = true;
      },
      mouseout: function () {
        disabledScroll = false;
        delayTimeSum = 0; // 清空
      }
    };
    // 移入时关闭自动滚动
    el.addEventListener( mouseover , customEvent.mouseover, false);
    // 移出时开启自动滚动
    el.addEventListener( mouseout , customEvent.mouseout, false);

    // 自动滚动
    let preTime = Date.now();
    let curTime = null;
    let diffTime = Math.max(...[1000 / 60, (1000 / 60) * speed]); // 动画间隔
    let mutiTime = 1 // 滚动时间倍数,滚动距离过短时,延长动画时间 - 经测这样效果最好
    let autoScroll = () => {
      if (scrollTarget.scrollHeight <= scrollTarget.clientHeight) return; // 无滚动条,不具备滚动条件
      if (disabledScroll) return;

      // 滚动距离过短,滚动时间延长
      if (scrollTarget.scrollHeight <= 1.8 * scrollTarget.clientHeight) {
        mutiTime = 2.5
      } else {
        mutiTime = 1
      }

      // 判断滚动条是否到底部
      if (scrollTarget.scrollHeight - scrollTarget.scrollTop <= scrollTarget.clientHeight) {
        // 触底后延迟 delayTime 再从头开始动画
        if (!touchBottom) {
          touchBottom = true
          delayTimeSum = 0; // 延迟再从头开始滚动
        } else {
          touchBottom = false
          scrollTarget.scrollTop = 0;
        }
      } else {
        scrollTarget.scrollTop += interval;
      }
    };
    (function animloop() {
      curTime = Date.now();
      if (curTime - preTime > diffTime * mutiTime) {
        // 在延迟时间内不执行动画
        if (delayTimeSum >= delayTime) {
          autoScroll();
        } else {
          delayTimeSum += curTime - preTime;
        }
        preTime = curTime;
      }
      el._customData.raId = requestAnimationFrame(animloop);
    })();
    el._customData.customEvent = customEvent;
  },
  /* eslint-disable no-unused-vars */
  unbind(el) {
    /* eslint-enable no-unused-vars */
    // 解绑
    let _customData = el._customData;
    if (!el || !_customData) return;
    cancelAnimationFrame(_customData.raId);
    el.removeEventListener( mouseover , _customData.customEvent.mouseover);
    el.removeEventListener( mouseout , _customData.customEvent.mouseout);
  }
});

效果如下

方式一:直接添加到滚动盒子上

    <ul class="test-box" v-auto-scroll>
      <li v-for="item in 20" :key="item">{{item}}</li>
    </ul>

vue 写个内容自动滚动的自定义指令 v-auto-scroll ,鼠标移入停止滚动,移出继续滚动

方式二: element-ui 的 el-table

v-auto-scroll="{
            targetSelector: .el-table__body-wrapper 
          }

vue 写个内容自动滚动的自定义指令 v-auto-scroll ,鼠标移入停止滚动,移出继续滚动

vue 写个内容自动滚动的自定义指令 v-auto-scroll ,鼠标移入停止滚动,移出继续滚动

若对你有协助,请点个赞吧,若能打赏不胜感激,谢谢支持!
本文地址:https://www.jianshu.com/p/e43ceee4aeca?v=1734601770680,转载请注明出处,谢谢。

© 版权声明
THE END
如果内容对您有所帮助,就支持一下吧!
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容