【问题标题】:Scroll to fixed points automatically using javascript/jquery使用 javascript/jquery 自动滚动到固定点
【发布时间】:2013-11-22 00:49:47
【问题描述】:

我有一个正在开发的应用程序,我希望它在用户向上或向下滚动时将其锁定到最近的锚点。

有没有已知的方法可以做到这一点?如果有人在 iPhone 上安装了 'circa' 应用程序,你就会知道我在说什么。

我有一个简单的破解解决方案可以检测滚动并执行以下操作:

var nearestAnchorOffset = calculateNearestAnchorOffset();
$('body').scrollTop(nearestAnchorOffset);

但是,它并不理想,因为它有时会非常紧张和不可预测。

一个问题似乎是滚动事件在滚动时触发开始,是否存在在滚动结束时触发的等效事件?

这是我试图让它工作的网站:

http://supi.hmp.is.it

请注意,该效果仅在小屏幕上触发(在桌面上并不真正需要)。我在滚动上使用了 jQuery debounce,以便它仅在用户 停止 滚动时触发。它在桌面上非常流畅,但是在 iPhone 上看时,它有 50% 的时间不能正确并滚动到错误的位置。

到目前为止,这是我的完整解决方案:

if($( document ).width() <= 768){
    var offsets = {};
    $( window ).scroll($.debounce(function(data) {
        if(isActive !== false){          
            // different scrollable points
            offsets.todaytitle      = $('.row.today.title').offset();
            offsets.todaywind       = $('.row.today.result .wind').offset();
            offsets.todaytemp       = $('.row.today.result .temp').offset();
            offsets.tomorrowtitle   = $('.row.tomorrow.title').offset();
            offsets.tomorrowwind    = $('.row.tomorrow.result .wind').offset();
            offsets.tomorrowtemp    = $('.row.tomorrow.result .temp').offset();
            offsets.form            = $('#postcodeForm').offset();
            offsets.nav             = $('#nav-bottom').offset();
            offsets.top             = {top: 0};

            var current = $(window).scrollTop();
            var closest = "";
            var curDiff = 99999;
            $.each(offsets, function( key, value ) {
                var diff = Math.abs(offsets[key].top - current);
                if(diff < curDiff){
                    curDiff = diff;
                    closest = key;
                }
            });

            animatedScroll(offsets[closest].top);
        }
    },350));
}

function animatedScroll(offset){
    $("body").animate({ scrollTop: offset },200, function() {
        scrollingOn = false;
    });
}

任何帮助将不胜感激!

【问题讨论】:

    标签: javascript jquery html css


    【解决方案1】:

    您没有包含您已经尝试过的内容,但我可以向您展示我最近针对此类问题所做的解决方案。

    单独使用scroll() 函数不会顺利处理它,因为拖动滚动条 可能是个大问题,我建议您使用mousewheel 事件来处理。

    通过将其与'DOMMouseScroll mousewheel' 事件绑定来进行锚定。然后使用originalEvent.wheelDelta获取鼠标滚轮的方向,向下滚动返回负值,向上滚动返回正值。

    $('body').bind('DOMMouseScroll mousewheel', function(e){
        var $anchored = $('section.anchored');      
    
        if(e.originalEvent.wheelDelta < 0) { //mousewheel down
            $next = $anchored.next();
    
            if($next.length){
                $('body').stop().animate({scrollTop:$next.offset().top},'slow');
                $anchored.removeClass('anchored')
                $next.addClass('anchored')     
            } 
        }else{ //mousewheel up
            $prev = $anchored.prev();
    
            if($prev.length){
                $('body').stop().animate({scrollTop:$prev.offset().top},'slow'); 
                $anchored.removeClass('anchored')
                $prev.addClass('anchored')   
            }
        }
        e.preventDefault();
    });
    

    现在,如果用户通过拖动滚动条进行滚动,您还需要将'anchored' 类指示器移动到视口中最明显的&lt;section&gt;

    $(window).scroll(function(){
        var st = $(this).scrollTop();
    
        $('section').each(function(){
            var offset = $(this).offset();
            if(st >= offset.top && st < offset.top + $(this).outerHeight()){
                $(this).addClass('anchored');
            }else{
                $(this).removeClass('anchored');
            }
        });
    });
    

    这是我的示例jsfiddle

    【讨论】:

    • 嗯,这是一个有趣的解决方案 - 我已经发布了一些关于我迄今为止尝试过的更多细节以及我正在开发的应用程序的链接,如果你在一个小窗口中查看它甚至在 iPhone 上更好,你会明白我的意思。它在桌面上运行良好,但 iPhone 给我带来了问题,它似乎没有在正确的位置触发滚动事件(它在正确的时间触发,但标记的位置似乎是手指离开的位置而不是静止位置动量之后)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-07-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-14
    相关资源
    最近更新 更多