满口金牙 2022-11-15 14:21 采纳率: 91.1%
浏览 3
已结题

Vue scroll 步进滚动的方法,请教优化方案

**函数的作用,用overflow元素, 内部显示完整的行.
**

<ul  id="currElement" @scroll='menuScrollX('currElement', 26)'>
    <li></li>
   ....


let scrollValue = 0 // 把本次的scrollTop,写入变量用于判断滚动方向
let scrollTimer:any = null

// Y向滚动轴调整,用于完整显示 一行
function menuScrollY(elementID: string, rowHeight = 26) {
    // 注意点:外部overflow元素的max-height高度, 应是 rowHeight 的倍数
    // elementID:  overflow元素的id
    // rowHeight:  overflow元素 内部行元素的行高
    let rowNumber = 1 // 行数
    const outElement = document.getElementById(elementID) as HTMLElement
    // 顶部不调整,但要记录 scrollValue 值
    if (outElement.scrollTop == 0) { scrollValue = 0;return }
    // 如果 scrollTop 值 为行高的倍数 也不调整
    if ((outElement.scrollTop % rowHeight) == 0) return


    // 根据scrollValue 值 判断滚动方向, 计算行数
    if (outElement.scrollTop > scrollValue) {  
        rowNumber = Math.ceil(outElement.scrollTop / rowHeight) // 向下滚动
    } else {
        rowNumber = Math.floor(outElement.scrollTop / rowHeight) // 向上滚动
    }

    // 使滚动的高度等于行高的倍数
    // 问题点, 这时scrollTop 不停修正,页面会抖动
    outElement.scrollTop = (rowNumber * rowHeight)  
    console.log('rowNumber', rowNumber,scrollValue)
    scrollValue = outElement.scrollTop  // 把本次的scrollTop,写入变量用于下次判断滚动方向


    // 问题点, 滚动停下后 ,修正一次,页会抖动一次
   //  if (scrollTimer !== null) { clearTimeout(scrollTimer)}
   //  scrollTimer = setTimeout(() => {
    //    outElement.scrollTop = (rowNumber * rowHeight) // 使滚动的高度等于行高的倍数
     //   scrollTimer = null
    // }, 200)

}

用seTimeout 页会抖动一次,不用滚动时, 会不停抖动,
说明我这方法有问题. 请教更好的方法
我看到网友的贴子,也指出类似的问题, 类似的方案不能平滑实现,目前没找到优化的方法

  • 写回答

4条回答 默认 最新

  • CSDN专家-showbo 2022-11-15 15:38
    关注

    可以用mousewheel(chrome)和DOMMouseScroll(Firefox)控制鼠标滚轮事件,只会触发一次,不需要防抖,但是拖动滚动条没法触发scorll。
    拖动滚动条scroll可以考虑调整容器scrollTop头为行高倍数

    <style>
        #container{overflow:auto;height:260px;border:solid 1px #aaa;max-width:680px;margin:0 auto}
        #container>div.item{line-height:26px}
        #container>div.item:nth-child(2n+1){background:#eee}
        #container>div.item{text-align:center;font-weight:bold}
    </style>
    <div id="container">
        <script>for (var i = 0; i < 50; i++)document.write(`<div class="item">${i}</div>`)</script>
    </div>
    <script>
        let container = document.querySelector('#container');
        let rowHeight = 26, rowNumber = 3;
        let byMouseWheel = false;
        function handleMouseWheel(e) {
            e.preventDefault();
            //deltaY(mousewheel有)和detail(DOMMouseScroll)小于0往上滚动
            let dir = (e.deltaY || e.detail) < 0 ? -1 : 1;
            byMouseWheel = true;
            container.scrollTop += dir * rowHeight * rowNumber;
            console.log(container.scrollTop, 'mousewheel')
            setTimeout(() => { byMouseWheel = false }, 1)
        }
        container.addEventListener('mousewheel', handleMouseWheel);
        container.addEventListener('DOMMouseScroll', handleMouseWheel)
        let timer;
        function handleScroll(e) {
            if (byMouseWheel) return false;//鼠标滚轮事件不执行
    
            console.log(container.scrollTop, 'scroll')
            container.scrollTop -= container.scrollTop % rowHeight;//这样不会抖,但是触发多次比较耗资源
    
            //防抖会跳一下,这个没法控制浏览器滚动的距离。除非改成隐藏容器自动生成的滚动条,改为用DOM模拟,拖动DOM用代码控制容器滚动,比如nicescroll
            /*
            clearTimeout(timer);
            timer = setTimeout(() => {
                container.scrollTop -= container.scrollTop % rowHeight
                console.log(container.scrollTop,'scroll')
            }, 150);*/
           
        }
        container.addEventListener('scroll', handleScroll, false);
    </script>
    
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(3条)

报告相同问题?

问题事件

  • 系统已结题 11月24日
  • 已采纳回答 11月16日
  • 创建了问题 11月15日

悬赏问题

  • ¥50 MATLAB APP 制作出现问题
  • ¥15 wannier复现图像时berry曲率极值点与高对称点严重偏移
  • ¥15 利用决策森林为什么会出现这样·的问题(关键词-情感分析)
  • ¥15 DispatcherServlet.noHandlerFound No mapping found for HTTP request with URI[/untitled30_war_e
  • ¥15 使用deepspeed训练,发现想要训练的参数没有梯度
  • ¥15 寻找一块做为智能割草机的驱动板(标签-stm32|关键词-m3)
  • ¥15 信息管理系统的查找和排序
  • ¥15 基于STM32,电机驱动模块为L298N,四路运放电磁传感器,三轮智能小车电磁组电磁循迹(两个电机,一个万向轮),怎么用读取的电磁传感器信号表示小车所在的位置
  • ¥15 如何解决y_true和y_predict数据类型不匹配的问题(相关搜索:机器学习)
  • ¥15 PB中矩阵文本型数据的总计问题。