【问题标题】:CSS 'snap-scroll' interfering with jQuery '.animate scrollLeft'CSS 'snap-scroll' 干扰 jQuery '.animate scrollLeft'
【发布时间】:2019-04-25 18:11:06
【问题描述】:

我有一个 html 和 css 滑块,我使用 scroll-snap 进行手动滚动,使用 jQuery 按钮进行自动滚动。但是,当使用scroll-snap-type: x mandatory; 时,jQuery 的scrollLeft 动画会变得非常滞后或动画消失。这种滞后来自哪里?有没有 jQuery 唯一的解决方案?

取出css scroll-snap 解决了问题,但是样式对slider来说是必须的。

HTML

<div class="container">
  <div class="box"></div>
  <div class="box"></div> 
  <div class="box"></div>
</div>
<button id="left">&larr;</button>
<button id="right">&rarr;</button>

CSS

.container {
  max-width: 300px;
  display: flex;
  scroll-snap-type: x mandatory;
  overflow-x: auto;
}
.box {
  min-width: 100%;
  min-height: 250px;
  scroll-snap-align: center;
  scroll-snap-stop: normal;
}
.box:nth-child(1) {background: #f55;}
.box:nth-child(2) {background: #5f5;}
.box:nth-child(3) {background: #5ff;}

jQuery

$("#right, #left").click(function() {
  var dir = this.id=="right" ? '+=' : '-=' ;
  $(".container").stop().animate({scrollLeft: dir+'300'}, 300);
});

这是一个活生生的例子:https://codepen.io/tystrong/pen/rboLYz

【问题讨论】:

  • 如果您将scroll-snap-type 规则更改为scroll-snap-type: x proximity;scroll-snap-type: x;(可能相同),您应该获得一些动画滚动。然而,在 Chrome 76.0.3809.132 中,动画滚动很卡/不流畅,scroll-snap-type: x mandatory; 为我的模块提供了出色的用户体验。因此,我不认为这是一个可行的解决方法,但出于调查目的想提一下。

标签: jquery html css


【解决方案1】:

我通过在滚动动画期间禁用 scroll-snap-type 属性解决了这个问题。然后在animate() 回调中我只是重新启用它。

这是我的简化代码:

$arrows.on("click", event => {
  $track.css("scroll-snap-type", "none");

  $track.stop().animate(
    { scrollLeft: left },
    500,
    () => $track.css("scroll-snap-type", "x mandatory")
  );
});

【讨论】:

  • 似乎对我不起作用 - 滚动位置只是恢复到重新添加强制时的预滚动位置
【解决方案2】:

smooth scroll behavior polyfill 提供了 jQuery animate 的可靠替代方案来解决这个侧滚动和捕捉问题。以下是您如何修改之前的示例以使用它:

$('#right, #left').click(function() {
  $('.container')[0].scrollBy({
    top      : 0,
    left     : this.id == 'right' ? 300 : -300,
    behavior : 'smooth'
  });
});

1 警告:您无法控制滚动速度。但是,在我对桌面 Chrome (76.0.3809.132) 和移动 Safari (iOS 13.0) 的测试中,它非常流畅。

【讨论】:

    【解决方案3】:

    解决方案是在要滚动到的元素(即滚动条内的框之一)上使用 JavaScript 的原生 scrollIntoView 方法。使用此方法,将使用本机滚动捕捉行为(和动画),并将 - 如果可用 - GPU 加速:它会看起来流畅和原生。

    在你的情况下,它会是这样的:

    var boxes = $(".box", ".container");
    var animate_to_id = 1; //make this dynamic, based on the current active id, and where you want to scroll to.
    
    boxes.eq(animate_to_id)[0].scrollIntoView({
        behavior: 'smooth',
        block: 'start',
        inline: 'start'
      });
    

    【讨论】:

    • 适用于 Chrome,但不适用于 iOS WKWebView (Safari) (iOS 15) =/
    • @RodrigoVieira 它应该可以工作,但如果我没记错的话,它不能提供平滑的过渡。查看更多信息@caniuse.com/?search=scrollIntoView
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-25
    • 1970-01-01
    • 1970-01-01
    • 2011-04-02
    • 1970-01-01
    相关资源
    最近更新 更多