You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修改点击拖拽滚动逻辑,实现跳转至对应Hash锚点?

实现拖拽跳转至最近Hash锚点的方案

我之前做了一个鼠标点击拖拽滚动页面的功能(无需滚轮),代码是这样的:

var clicked = false, clickY; 
$(document).on({ 
    'mousemove': function(e) { 
        clicked && updateScrollPos(e); 
    }, 
    'mousedown': function(e) { 
        clicked = true; 
        clickY = e.pageY; 
    }, 
    'mouseup': function() { 
        clicked = false; 
        $('html').css('cursor', 'auto'); 
    } 
}); 
var updateScrollPos = function(e) { 
    $('html').css('cursor', 'row-resize'); 
    $(window).scrollTop($(window).scrollTop() + (clickY - e.pageY)); 
}

后来我想升级这个功能:当拖拽距离达到10px左右时,直接跳转到当前位置上下最近的Hash锚点——往上拖就跳上面的锚点,往下拖就跳下面的锚点。我知道核心是要替换掉updateScrollPos里的滚动代码,但自己搞不定具体实现。

后来参考了相关方案,最终采用了Saeed Ataee的思路,把原来的拖拽逻辑和锚点跳转结合起来,替换掉了滚轮相关的代码,效果比预期的好,最终代码如下:

$('#nav').onePageNav(); 
var $current, flag = false, clicked = false, clickY; 

$('body')
.on('mousemove', function(e) {
    if (!clicked || flag) return;
    
    var moveDistance = clickY - e.pageY;
    // 拖拽距离超过10px时触发锚点跳转
    if (Math.abs(moveDistance) > 10) {
        flag = true;
        $current = $('div.current');
        
        if (moveDistance > 0) {
            // 向上拖拽,定位到上一个锚点元素
            var $prev = $current.prev();
            if ($prev.length) {
                $('body').scrollTo($prev, 1000, { 
                    onAfter : function(){ 
                        flag = false;
                        $current.removeClass('current'); 
                        $prev.addClass('current'); 
                    } 
                });
            } else {
                // 已经是第一个元素,重置标记
                flag = false;
            }
        } else {
            // 向下拖拽,定位到下一个锚点元素
            var $next = $current.next();
            if ($next.length) {
                $('body').scrollTo($next, 1000, { 
                    onAfter : function(){ 
                        flag = false;
                        $current.removeClass('current'); 
                        $next.addClass('current'); 
                    } 
                });
            } else {
                // 已经是最后一个元素,重置标记
                flag = false;
            }
        }
        
        // 跳转触发后暂时关闭拖拽状态,避免重复触发
        clicked = false;
        $('html').css('cursor', 'auto');
    }
})
.on('mousedown', function(e) {
    clicked = true;
    clickY = e.pageY;
    flag = false; // 每次点击都重置跳转标记
})
.on('mouseup', function() {
    clicked = false;
    $('html').css('cursor', 'auto');
});

这里的关键逻辑是:

  • 记录鼠标按下时的Y坐标,拖拽时计算移动距离
  • 当移动距离超过10px时,根据方向判断是找前一个还是后一个锚点元素
  • 用flag标记避免跳转过程中重复触发事件
  • 跳转完成后更新当前激活的锚点类名,同时重置标记

内容的提问来源于stack exchange,提问作者user8139445

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 07:26:14