可滚动面板捕捉到滚动上的元素

发布于 2024-11-26 04:42:24 字数 1013 浏览 1 评论 0原文

有没有一种方法可以在可滚动 div 内随着用户滚动来捕捉元素。

例如,如果我们有CSS(如)

.container {
    height: 300px;
    width: 200px;
    overflow: auto
}
li {
    height: 40px;
    width: 100 % ;
}

和HTML(如

<div class="container">
    <li>
        test
    </li>
    <li>
        test
    </li>
    <li>
        test
    </li>
    <li>
        test
    </li>
    <li>
        test
    </li>
    <li>
        test
    </li>
    <li>
        test
    </li>
    <li>
        test
    </li>
    <li>
        test
    </li>
    <li>
        test
    </li>
    <li>
        test
    </li>
    <li>
        test
    </li>
    <li>
        test
    </li>
</div>

),那么容器应该有一个垂直滚动条。当用户滚动时,我希望这样当他们停止滚动时,最终滚动位置会将容器滚动位置捕捉到显示的最近的 div。这可能很困难,因为像 safari 这样的浏览器也提供动力,所以它必须是滚动端的事件。

任何想法是否可能,以及如何实现。

奇妙

Is there a way inside a scrollable div to snap to elements as the user scrolls.

For example if we have CSS such as

.container {
    height: 300px;
    width: 200px;
    overflow: auto
}
li {
    height: 40px;
    width: 100 % ;
}

and HTML as

<div class="container">
    <li>
        test
    </li>
    <li>
        test
    </li>
    <li>
        test
    </li>
    <li>
        test
    </li>
    <li>
        test
    </li>
    <li>
        test
    </li>
    <li>
        test
    </li>
    <li>
        test
    </li>
    <li>
        test
    </li>
    <li>
        test
    </li>
    <li>
        test
    </li>
    <li>
        test
    </li>
    <li>
        test
    </li>
</div>

So from that the container should have a vertical scroll bar. When the user scrolls I would like it so that when they stop scrolling the final scroll position snaps the container scroll position to the nearest div at shown. This might be difficult as browsers like safari offer momentum as well, so it would have to be an event on scroll end.

Any ideas if this is possible, and how.

Marvellous

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

指尖微凉心微凉 2024-12-03 04:42:24

可以使用setTimeout。这应该有效

var snap_timer;
var scroll_from_mouse = true;

function snapList(){
  var snapped = false;
  var i = 0;
  while(!snapped && i < $('.container li').size()){
    var itop = $('.container li').eq(i).position().top;
    var iheight = $('.container li').eq(i).outerHeight();
    if(itop < iheight && itop > 0){ 
      scroll_from_mouse = false;
      snapped = true;
      var new_scroll_top = 0;
      if(iheight - itop > iheight / 2)
        new_scroll_top = $('.container').scrollTop() + itop;
      else if(i > 1)
        new_scroll_top = $('.container').scrollTop() - ($('.container li').eq(i-1).outerHeight() - itop);
      else
        new_scroll_top = 0;
      $('.container').scrollTop(new_scroll_top);
    }
    i++;
  }
};

$(function(){
  $('.container').scroll(function(){
    clearTimeout(snap_timer);
    if(scroll_from_mouse) snap_timer = setTimeout(snapList, 200);
    scroll_from_mouse = true;
  });
});

You can use setTimeout. This should work

var snap_timer;
var scroll_from_mouse = true;

function snapList(){
  var snapped = false;
  var i = 0;
  while(!snapped && i < $('.container li').size()){
    var itop = $('.container li').eq(i).position().top;
    var iheight = $('.container li').eq(i).outerHeight();
    if(itop < iheight && itop > 0){ 
      scroll_from_mouse = false;
      snapped = true;
      var new_scroll_top = 0;
      if(iheight - itop > iheight / 2)
        new_scroll_top = $('.container').scrollTop() + itop;
      else if(i > 1)
        new_scroll_top = $('.container').scrollTop() - ($('.container li').eq(i-1).outerHeight() - itop);
      else
        new_scroll_top = 0;
      $('.container').scrollTop(new_scroll_top);
    }
    i++;
  }
};

$(function(){
  $('.container').scroll(function(){
    clearTimeout(snap_timer);
    if(scroll_from_mouse) snap_timer = setTimeout(snapList, 200);
    scroll_from_mouse = true;
  });
});
や三分注定 2024-12-03 04:42:24

您可以使用 CSS 滚动对齐

但是,该功能现已弃用,因此如果您想考虑跨浏览器原生 javascript 重新实现本机 CSS Scroll Snap 规范,如此处已回答的:如何在 Chrome 中模拟 CSS 滚动捕捉点?,你可以使用

这个库是我写的。

使用此解决方案而不是本机 CSS 解决方案的主要原因是它适用于所有现代浏览器,并且具有可自定义的配置,允许在转换和滚动检测中自定义计时。

该库使用普通的 javascript 缓动函数重新实现了 css 捕捉功能,并使用容器元素的 scrollTop/scrollLeft 属性和 scroll 的值进行工作。 em> 事件监听器

这是一个展示如何使用它的示例:

import createScrollSnap from 'scroll-snap'

const element = document.getElementById('container')

const { bind, unbind } = createScrollSnap(element, {
  snapDestinationX: '0%',
  snapDestinationY: '90%',
  timeout: 100,
  duration: 300,
  threshold: 0.2,
  snapStop: false,
  easing: easeInOutQuad,
}, () => console.log('snapped'))

// remove the listener 
// unbind();

// re-instantiate the listener 
// bind();

您可以看到一个工作演示 这里

You can use CSS Scroll Snap.

However, the feature is now deprecated, so if you want to consider a cross-browser vanilla javascript re-implementation of the native CSS Scroll Snap spec, as already answered here: How to emulate CSS Scroll Snap Points in Chrome?, you can use

this library
I wrote.

The main reason to use this instead of the native css solution is that it works in all modern browsers and has a customizable configuration to allow custom timing in transitions and scrolling detection.

The library re-implements the css snapping feature using vanilla javascript easing functions, and works using the values of the container element's scrollTop/scrollLeft properties and the scroll Event Listener

Here is an example that shows how to use it:

import createScrollSnap from 'scroll-snap'

const element = document.getElementById('container')

const { bind, unbind } = createScrollSnap(element, {
  snapDestinationX: '0%',
  snapDestinationY: '90%',
  timeout: 100,
  duration: 300,
  threshold: 0.2,
  snapStop: false,
  easing: easeInOutQuad,
}, () => console.log('snapped'))

// remove the listener 
// unbind();

// re-instantiate the listener 
// bind();

You can see a working demo here

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文