【问题标题】:Scroll snapping to a page section滚动捕捉到页面部分
【发布时间】:2015-12-02 05:04:29
【问题描述】:

所以我在页面顶部附近有两个内容部分,我希望向下滚动到第二部分顶部接近的用户能够“滚动捕捉”到一旦他们停止滚动,第二个的顶部。

我认为使用 jQuery 应该是可能的,但我无法弄清楚。这是我的例子:

基本上我不知道如何让它在滚动停止后只尝试滚动到该位置一次。这有点吓坏了。

我喜欢最近推出的scroll snap points CSS feature 处理滚动捕捉的方式,我几乎更喜欢使用它——至少对于支持它的浏览器——但它似乎只适用于占 100% 的项目视口的高度或宽度,它似乎是用于在元素内滚动,而不是页面本身。

顶部有一个固定的高度,所以这真的可以用像素数来处理。


作为参考,这是我尝试的代码的核心:

$(function() {
  $(document).on('scroll', function() {
    var top = $(document).scrollTop();
    if (top > 255 && top < 455) {
      $('html, body').animate({scrollTop: '356'}, 500);
      $('body').addClass('hotzone');
    } else {
      $('body').removeClass('hotzone');
    }
  });
});

【问题讨论】:

    标签: javascript jquery html css scroll


    【解决方案1】:

    KQI 的答案包含创建功能良好的部分滚动所需的大部分步骤,以便在您的应用程序/网页中使用。

    但是,如果您只是想自己试验一下,进一步开发您的脚本,您要做的第一件事就是添加一个超时处理程序。否则,您的逻辑以及 scrollAnimation 将触发每个滚动的像素并创建错误的弹跳效果。

    我在这里提供了一个基于您的脚本的工作示例: http://codepen.io/anon/pen/QjepRZ?editors=001

    $(function() {
      var timeout;
      $(document).on('scroll', function() {
        clearTimeout(timeout);
        timeout = setTimeout(function() {
          var top = $(document).scrollTop();
          if (top > 255 && top < 455) {
            $('body').animate({
              scrollTop: '356'
            }, 500);
            $('body').addClass('hotzone');
          } else {
            $('body').removeClass('hotzone');
          }
        }, 50);
    
      });
    });
    

    祝你好运!

    【讨论】:

    • 这太棒了,几乎完美!谢谢你的建议。但是,当我尝试滚动时,我仍然看到“错误的弹跳效果”(a)它正在移动或(b)它已经捕捉到一段时间后(如果我滚动缓慢)。有什么方法可以防止在用户滚动时 snap 尝试工作?
    • 很高兴能够提供帮助:) 至于滚动缓慢的问题,我认为可能很难捕捉到。由于您的动画本身实际上会触发滚动事件,因此我看不到检测用户是否进行滚动并停止动画的方法。我会尝试一些然后回复你。如果对您有帮助,请不要忘记接受答案:)
    • 我在这里有一个更新的版本 (codepen.io/anon/pen/adooGm?editors=001) 有一些额外的检查用户是否启动了滚动。但是,如果您使用启动另一个动画的滚动条滚动很少的像素,错误仍然存​​在。这个问题我找不到atm的解决方案。祝你好运! :)
    • 非常感谢!我试图奖励你这个解决方案的赏金,但我说我出于某种原因必须等待 23 小时。
    • 一个相关的问题,你认为有可能检测到用户何时脱离了滚动控制器吗? (在 Macbook 触控板上,当他们移除启动滚动的两个手指之一时。)Safari 的滚动捕捉点 CSS 功能的实现似乎基于“何时开始捕捉”。
    【解决方案2】:

    好吧,要获得好的结果,您必须处理几件事:性能、调用堆栈队列、缓动。

    在性能方面,您应该放弃 jQuery animate 并使用 VelocityJs,它可以提供更平滑的过渡、更好的每秒帧数 (fps) 以避免屏幕故障,尤其是在移动设备上。

    调用堆栈:您应该使用“去抖动”功能包装您必须为滚动顶部设置动画的任何逻辑,将延迟设置为 500 毫米并检查滚动行为。就像您知道的那样,您使用的“滚动”侦听器会在每个像素更改时触发,您的脚本会变得疯狂和不稳定。 (这将是同时进行这么多计算的时刻。Debounce 会为您解决这个问题)

    轻松:让过渡看起来很酷,而不仅仅是干脆利落的动作。

    请记住,Velocity 的“缓动”以“mina”开头。即

    'Mina.easingFnName'
    

    最后,您的逻辑可能是正确的,我现在在手机中无法调试它,但尝试简化它并立即处理一个问题,就像即

    If ( top > 380 )  // debounce(...)
    

    【讨论】:

    • 在加载动画脚本之前不要忘记添加 debounce fn
    • 感谢您的建议。我肯定想看看 VelocityJS,但到目前为止,我一直在坚持这个项目的大部分 CSS 过渡。我想尝试使用去抖动功能,但我不熟悉它们。有没有机会你能给我指出一个很好的例子吗?谢谢!
    • 当然,试试这个:tinyurl.com/odvpj6f 通知 debounce 总是返回一个函数,所以要运行 debounced 函数传递额外的大括号'()'。即去抖动(function () { ... }, 400)();
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-04
    • 2021-02-20
    • 2016-09-13
    • 2020-03-30
    • 1970-01-01
    • 2016-04-19
    相关资源
    最近更新 更多