如何“捕捉”滚动到最近的预定义位置?

时间:2012-12-07 02:52:01

标签: javascript jquery scroll

我有一个基本上是四个div的网站 - 每个div都设置为窗口的高度,这样总文档就是窗口高度的四倍。

这个想法是点击一个div将滚动推进一个“窗口高度” - 这很好,就像这样:

// on click event

if(cur_frame<number_slides){
   scrolling = true;
   $('html,body').animate({scrollTop:window_height*cur_frame},function(){
      scrolling=false;
   });
}

然而,在用户手动滚动页面之后,我想将位置“捕捉”到窗口高度的最近倍数 - 因此给定的div再次居中在屏幕上。我尝试使用超时,认为一个小的延迟会阻止它每秒触发一千次......

// on scroll event

clearTimeout(scroll_timer);
if(!scrolling) scroll_timer = setTimeout(function(){
   if(cur_scroll!=window_height*(cur_frame-1)) {
      scrolling = true;
      $('html,body').stop().animate({scrollTop:window_height*(cur_frame-1)},function(){
         scrolling = false;
      });
   }
},100); //20? 400? 1000?

...但是无法在用户对滚动位置进行战斗的脚本之间取得平衡,或者在一个严重的长时间延迟中击败“捕捉”效果。

有关如何实现这一目标的任何建议吗?

5 个答案:

答案 0 :(得分:4)

这个jquery scrollsnap插件支持IE9。

您正在寻找的内容称为“Scroll Snap”。

<script src="demo/foundation/javascripts/jquery.js"></script>
<script src="src/jquery.event.special.js"></script>
<script src="src/jquery.easing.min.js"></script>
<script src="src/jquery.scrollsnap.js"></script>
<script type="text/javascript">
$(document).ready(function() {
    $(document).scrollsnap({
        snaps: '.snap',
        proximity: 50
    });
});
</script>

答案 1 :(得分:2)

有一个CSS规范,除了Chrome之外,它还支持原生渲染和非常好的触摸行为:http://caniuse.com/#feat=css-snappoints

对于落后的浏览器,有一个polypill:https://github.com/ckrack/scrollsnap-polyfill

另见How to emulate CSS Scroll Snap Points in Chrome?

答案 2 :(得分:0)

如果你想考虑一个跨浏览器的javascript重新实现原生CSS Scroll Snap 规范,已经在这里回答:How to emulate CSS Scroll Snap Points in Chrome?,你可以使用 的 this library

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

库使用vanilla javascript缓动函数重新实现css捕捉功能,并使用容器元素的scrollTop / scrollLeft属性和滚动事件的值进行工作听者

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

import ScrollSnap from 'scroll-snap'

const snapConfig = {
  scrollSnapDestination: '90% 0%', // scroll-snap-destination css property, as defined here: https://developer.mozilla.org/en-US/docs/Web/CSS/scroll-snap-destination
  scrollTimeout: 100, // time in ms after which scrolling is considered finished
  scrollTime: 300 // time in ms for the smooth snap
}

function callback () {
  console.log('called when snap animation ends')
}

const element = document.getElementById('container')
const snapObject = new ScrollSnap(element, snapConfig)

snapObject.bind(callback)

// unbind the element
// snapObject.unbind();

答案 3 :(得分:0)

使用简单的scrollTo怎么样?使用纯Javascript和CSS,没有框架或库。

这里有两个示例,一个用于垂直滚动,另一个用于水平滚动:

最佳
Unkn0wn0x

答案 4 :(得分:-1)

您可以使用javascript执行此操作,或者使用更简单,更旧的解决方案,您可以使用页面锚点。 如果将document.location.hash更改为页面中存在的锚点,则浏览器将滚动到该页面。 因此,在您的HTML中,在页面中添加了一些锚点:

<a name="anchor1" id="anchor1"></a>

然后在你的js put:

document.location.hash = "anchor1";