Javascript 仅对html禁用弹跳滚动,但对溢出的元素保持:滚动

Javascript 仅对html禁用弹跳滚动,但对溢出的元素保持:滚动,javascript,css,webkit,ios5,overflow,Javascript,Css,Webkit,Ios5,Overflow,我正在创建一个全屏web应用程序,其中将包含一些模块/小部件,这些模块/小部件利用了新的iOS 5 overflow:scroll功能。 我想要的是在滚动html/正文时禁用“反弹”效果(因为它是全屏的),但只在可滚动的元素上保持这种效果 要平滑可滚动元素的效果,我有: html, body { overflow: hidden; } .scrollable { overflow: scroll; -webkit-overflow-scrolling: touch; } 然后

我正在创建一个全屏web应用程序,其中将包含一些模块/小部件,这些模块/小部件利用了新的iOS 5 overflow:scroll功能。 我想要的是在滚动html/正文时禁用“反弹”效果(因为它是全屏的),但只在可滚动的元素上保持这种效果

要平滑可滚动元素的效果,我有:

html, body { overflow: hidden; }

.scrollable {
    overflow: scroll;
    -webkit-overflow-scrolling: touch;
}
然后是以下禁用触摸滚动效果的脚本:

$(document).bind('touchmove', function (e) { 
    if (e.target === document.documentElement) {
        e.preventDefault(); 
    }
});
尽管这似乎根本不起作用,因为当滚动一个元素到底部或顶部时,它也会滚动
documentElement

有没有办法只对body html元素禁用该效果

这是一个很好的例子,说明了这是如何影响功能的:


不幸的是,
-webkit溢出滚动
无法更好地处理此问题。您需要跟踪
y
位置才能使其工作。我将类
scroll
放在我想在页面上滚动的任何内容上,例如
元素。将
包裹在用
溢出-y:auto
填充视口的
周围。不要将
溢出
高度
放在
上。
将扩展到其内容的高度,而真正进行滚动的是
<代码>-webkit溢出滚动是继承的,因此请将其尽可能地放在DOM中

演示:

脚本:

var swipeY=0;
函数onTouchMove(事件){
var scroll=event.target.closestByClassName('scroll');
如果(滚动){
var top=scroll.positionTop-scroll.parentNode.positionTop,
高度差=(0-scroll.offsetHeight+scroll.parentNode.offsetHeight);
如果((顶部>=0)&&(event.touchs[0].screenY>swipeY)){
event.preventDefault();//在顶部,向下滑动
}否则如果((顶部-1
这
:(this.parentNode.closestByClassName&&this.parentNode.closestByClassName(className));
};
window.Object.defineProperty(Element.prototype,“positionTop”{
get:function(){
返回this.offsetTop-this.parentNode.scrollTop;
}
} );
document.getElementById('viewport').addEventListener('touchmove',onTouchMove,false);
document.getElementById('viewport').addEventListener('touchstart',onTouchStart,false);
HTML:


  • 滚动
  • 滚动
  • 滚动
  • . . .
CSS:

#视口{
边框:1px纯黑;
高度:460px;
宽度:320px;
-webkit溢出滚动:触摸;
}
#滚动视图{
身高:100%;
溢出y:自动;
宽度:100%;
}

这里有一个与ThinkingStiff类似的答案,不同的是它不强制要求您的html结构。它查找任何内容溢出的元素,并且仅当用户与它们交互时才启用滚动

缺点:

  • 一旦用户达到可滚动节点的上限或下限,该节点内将不会发生反弹(但如果从下限/上限上轻弹,则会发生反弹)。这可能意味着它不满足您的拉刷新要求:(

  • 在计算滚动偏移量时,我在测试用例中注意到一个奇怪的2px差异。不确定这是从哪里来的,您可能需要调整该值

咖啡脚本:

# Vertical scrolling behavior overrides.
#
# This disables vertical scrolling on the page for touch devices, unless the user is scrolling
# within an overflowed node.  This requires some finessing of the touch events.
#
# **NOTE:** This code ends up disabling bounce behavior if the user tries to scroll on a node that
# is already at its upper or lower limit.
window$   = $(window)
initialY  = null
nodeStack = []

# When a user begins a (potential) drag, we jot down positional and node information.
#
# The assumption is that page content isn't going to move for the duration of the drag, and that
# it would also be awkward if the drag were to change/stop part way through due to DOM
# modifications.
window$.bind 'touchstart', (evt) ->
  initialY  = evt.originalEvent.pageY
  nodeStack = $(evt.target).parents().andSelf().filter(':not(body, html)').get().reverse()
  nodeStack = nodeStack.map (node) -> $(node)

window$.bind 'touchend touchcancel', (evt) ->
  initialY  = null
  nodeStack = []

# We override the `touchmove` event so that we only allow scrolls in allowable directions,
# depending on where the user first began the drag.
window$.bind 'touchmove', (evt) ->
  return evt.preventDefault() if initialY == null
  # A positive direction indicates that the user is dragging their finger down, thus wanting the
  # content to scroll up.
  direction = evt.originalEvent.pageY - initialY

  for node$ in nodeStack
    nodeHeight    = node$.height()
    # For some reason, the node's scrollHeight is off by 2 pixels in all cases.  This may require
    # tweaking depending on your DOM.  Concerning.
    scrollHeight  = node$[0].scrollHeight - 2
    nodeScrollTop = node$.scrollTop()

    # If we have a scrollable element, we want to only allow drags under certain circumstances:
    if scrollHeight > nodeHeight
      # * The user is dragging the content up, and the element is already scrolled down a bit.
      return if direction > 0 and nodeScrollTop > 0
      # * And the reverse: the user is dragging the content down, and the element is up a bit.
      return if direction < 0 and nodeScrollTop < scrollHeight - nodeHeight

  # Otherwise, the default behavior is to disable dragging.
  evt.preventDefault()
垂直滚动行为覆盖。 # #这将禁用触摸设备页面上的垂直滚动,除非用户正在滚动 #在溢出的节点内。这需要对触摸事件进行一些处理。 # #**注意:**如果用户试图在以下节点上滚动,则此代码将禁用反弹行为: #已处于其上限或下限。 窗口$=$(窗口) initialY=null nodeStack=[] #当用户开始(潜在)拖动时,我们会记下位置和节点信息。 # #假设页面内容在拖动期间不会移动,并且 #由于DOM的原因,如果拖动中途改变/停止,也会很尴尬 #修改。 窗口$.bind“touchstart”(evt)-> initialY=evt.originalEvent.pageY nodeStack=$(evt.target).parents().andSelf().filter(':not(body,html)').get().reverse() nodeStack=nodeStack.map(节点)->$(节点) 窗口$.bind'touchend touchcancel'(evt)-> initialY=null nodeStack=[] #我们重写了“touchmove”事件,因此只允许在允许的方向上滚动, #取决于用户第一次开始拖动的位置。 窗口$.bind'touchmove'(evt)-> 如果initialY==null,则返回evt.preventDefault() #正向表示用户正在向下拖动手指,因此希望 #要向上滚动的内容。 方向=evt.originalEvent.pageY-初始值 对于nodeStack中的节点$ 节点高度=节点$.height() #由于某些原因,节点的滚动高度在所有情况下都会降低2像素。这可能需要 #根据您的DOM进行调整。 scrollHeight=节点$[0]。scrollHeight-2 nodeScrollTop=节点$.scrollTop() #如果我们有一个可滚动的元素,我们只希望在某些情况下允许拖动: 如果滚动高度>节点高度 #*用户正在向上拖动内容,元素已经向下滚动了一点。 如果方向>0且nodeScrollTop>0,则返回 #*反之:用户向下拖动内容,元素向上移动一点。 如果方向<0且节点滚动顶部<滚动高度-节点高度,则返回 #否则,默认行为是禁用拖动。 evt.preventDefault()
事实证明,对我来说,唯一有效的解决方案是使用脚本,它工作得非常好,没有延迟,我说