我使用iScroll解决了这个问题,它具有动量滚动的感觉和其他功能。
https://github.com/cubiq/iscroll GitHub文档很好,我基本上遵循了它。以下是我的实现细节。
HTML:
我用一些div包装了可滚动区域的内容,以供iScroll使用:
<div id="wrapper">
<div id="scroller">
... my scrollable content
</div>
</div>
CSS:
我使用了 Modernizr 类中的 "touch" 以仅针对触摸设备进行样式更改(因为我只在触摸设备上实例化 iScroll)。
.touch #wrapper {
position: absolute;
z-index: 1;
top: 0;
bottom: 0;
left: 0;
right: 0;
overflow: hidden;
}
.touch #scroller {
position: absolute;
z-index: 1;
width: 100%;
}
JS:
我从iScroll下载中包含了iscroll-probe.js,然后按照下面的方式初始化滚动条,其中updatePosition是我的函数,用于响应新的滚动位置。
if Modernizr.touch
myScroller = new IScroll('#wrapper', probeType: 3)
myScroller.on 'scroll', updatePosition
myScroller.on 'scrollEnd', updatePosition
现在必须使用myScroller来获取当前位置,而不是查看滚动偏移量。以下是从http://markdalgleish.com/presentations/embracingtouch/中提取的函数(一篇非常有帮助的文章,但现在有点过时了)
function getScroll(elem, iscroll) {
var x, y;
if (Modernizr.touch && iscroll) {
x = iscroll.x * -1;
y = iscroll.y * -1;
} else {
x = elem.scrollTop;
y = elem.scrollLeft;
}
return {x: x, y: y};
}
唯一的问题是,有时我会失去我想要滚动到的页面的一部分,并且它会拒绝滚动。每当我更改#wrapper的内容时,我不得不添加一些调用myScroller.refresh()的代码,这样就解决了这个问题。
编辑:另一个问题是iScroll会吞掉所有"click"事件。我打开了选项,让iScroll发出"tap"事件并处理那些事件,而不是"click"事件。幸运的是,在滚动区域中我不需要太多点击,所以这不是什么大问题。
window.pageYOffset
,而不能像其他所有浏览器/硬件一样使用document.body.scrollTop || document.documentElement.scrollTop
。 - ck_