有条件地阻止移动safari中的滚动/触摸移动事件

iOS 5现在允许本机溢出:滚动支持。

我想要做的是禁用touchmove事件除了具有’scrollable’类或其子元素的元素之外的所有内容。

但我似乎无法让它发挥作用; 这是我一直在下面工作的:

    .scrollable { height: 5em; overflow-y: scroll; -webkit-overflow-scrolling: touch; }    // doesn't seem to work var handleMove = function (e) { if (!$(e.target).parents().andSelf().hasClass('scrollable')) { e.preventDefault(); } }; document.addEventListener('touchmove', handleMove, true);    
don't scroll if you drag here
should be scrollable if you drag here
  • and here
  • and here
  • and here
  • and here
  • and here
  • and here
  • and here
  • and here
don't scroll if you drag here

我知道你问了这个问题已经有一段时间了,但我遇到了同样的问题,我用你的代码作为解决问题的基础。 所以感谢你的灵感。

(Javascript + jQuery)

  

或者更简洁,但最终结果相同(信用J Griffiths):

  

您还应该包含以下META标记。

  

基于Nevirs的JavaScript版本答案:

 var initialY = null; var nodeStack = []; var $window = $(window); $window.bind('touchstart', function(e) { initialY = e.originalEvent.pageY; nodeStack = $(e.target).parents().andSelf().filter(':not(body, html)').get().reverse(); nodeStack = nodeStack.map(function(node) { return $(node); }); }); $window.bind('touchend touchcancel', function(e) { initialY = null; nodeStack = []; }); $window.bind('touchmove', function(e) { if (!initialY) { e.preventDefault(); } var direction = e.originalEvent.pageY - initialY; for (var i = 0; i < nodeStack.length; i +=1) { var $node = nodeStack[i]; var nodeHeight = $node.height(); var scrollHeight = $node[0].scrollHeight - 2; var nodeScrollTop = $node.scrollTop(); if (scrollHeight > nodeHeight) { // the user is dragging the content up, and the element is already scrolled down a bit. var allowedUp = direction > 0 && nodeScrollTop > 0; // the user is dragging the content down, and the element is up a bit. var allowedDown = direction < 0 && nodeScrollTop < scrollHeight - nodeHeight; if (allowedUp || allowedDown) { return; } } } // disable drag e.preventDefault(); }); 

如果你在jquery document.ready事件中写这个,它会工作。

 $('body').on('touchmove', function (e) { if ($(e.target).closest("your_scrollable_div_selector").length == 0) e.preventDefault(); }); 

我尝试了斯科特的答案,但它在我的iphone iOS 5.1.1上无效

此外,如果您正在构建一个webClip应用程序,这一点尤其重要,我希望iOS 6允许video标记禁用自动弹跳

我的下面的版本与上面的Scott的答案一样有效(或没有),因为它基本上做同样的事情。

jQuery 1.7.2

  $(document).bind("touchmove",function(e){ e.preventDefault(); }); $('.scrollable').bind("touchmove",function(e){ e.stopPropagation(); }); 

我们可以使用touchstart事件而不是touchmove事件。 在One Finger Events下,它表示在平移期间没有发送任何事件,因此触摸移动可能为时已晚。

我将监听器添加到文档中,而不是正文。

 document.ontouchstart = function(e){ e.preventDefault(); } 

这是一个(主要)工作解决方案,用于禁用除溢出元素之外的所有内容的垂直滚动:

(CoffeeScript的):

 # 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()