在移动safari中有条件地阻止滚动/触摸事件
Conditionally block scrolling/touchmove event in mobile safari
iOS 5现在支持原生溢出:滚动
我想做的是禁用touchmove
事件的所有元素,除了具有'scrollable'类或其子元素。
但我似乎不能让它工作;这是我一直在下面工作的:
<html>
<head>
<style>
.scrollable {
height: 5em;
overflow-y: scroll;
-webkit-overflow-scrolling: touch;
}
</style>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script>
// doesn't seem to work
var handleMove = function (e) {
if (!$(e.target).parents().andSelf().hasClass('scrollable')) {
e.preventDefault();
}
};
document.addEventListener('touchmove', handleMove, true);
</script>
</head>
<body>
<div>
don't scroll if you drag here
</div>
<div class='scrollable'>
should be scrollable if you drag here
<ul>
<li>and here</li>
<li>and here</li>
<li>and here</li>
<li>and here</li>
<li>and here</li>
<li>and here</li>
<li>and here</li>
<li>and here</li>
</ul>
</div>
don't scroll if you drag here
</body>
</html>
我知道自从你问这个问题已经有一段时间了,但我有同样的问题,我用你的代码作为解决问题的基础。谢谢你的启发。
(Javascript + jQuery)<script>
var handleMove = function (e) {
var scrollable = false;
var items = $(e.target).parents();
$(items).each(function(i,o) {
if($(o).hasClass("scrollable")) {
scrollable = true;
}
});
if(!scrollable)
e.preventDefault();
};
document.addEventListener('touchmove', handleMove, true);
</script>
或者不那么冗长,但最终结果相同(归功于J Griffiths):
<script>
var handleMove = function (e) {
if($(e.target).closest('.scrollable').length == 0) { e.preventDefault(); }
}
document.addEventListener('touchmove', handleMove, true);
</script>
你还应该包括以下META标签。
<meta name="viewport" content="width=device-width, initial-scale=1.0,
maximum-scale=1.0, user-scalable=no;" />
基于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文档中写这个。准备好它将工作。
$('body').on('touchmove', function (e) {
if ($(e.target).closest("your_scrollable_div_selector").length == 0)
e.preventDefault();
});
我尝试了Scott的答案,但它在我的iphone iOS 5.1.1上不起作用
另外,如果你正在构建webClip应用,这一点尤其重要,天哪,我真希望iOS 6能允许一个viewport标签来禁用自动弹跳
我下面的版本和Scott上面的答案一样有效(或不有效),因为它本质上是一样的。
jQuery是1.7.2 $(document).bind("touchmove",function(e){
e.preventDefault();
});
$('.scrollable').bind("touchmove",function(e){
e.stopPropagation();
});
我们可以使用touchstart事件代替touchmove事件。在One Finger Events下,它说在平移过程中不会发送任何事件,所以touchmove可能太晚了。
我将侦听器添加到文档中,而不是添加到正文中。
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()
相关文章:
- 谷歌地图劫持了iphone's滚动(触摸事件)-如何恢复
- 如何检测滚动事件是否像在触摸设备上一样只触发一次
- Sencha触摸:工具栏无法正常滚动
- jQuery触摸滑动内容滚动功能
- 停止触摸滚动还可以防止单击链接
- 移动/触摸屏幕 - 滑动时水平滚动
- 允许在隐藏溢出的情况下进行触摸滚动
- 整页.js触摸滚动固定元素
- 检测触摸向上或向下滚动
- 移动HTML:触摸结束后继续滚动
- JS中的触摸板滚动检测,没有库
- 拖动滚动触摸设备,如手机/ iPad
- 在触摸设备上,滚动是使用 javascript 创建的,如何防止触摸触发单击
- 拉动刷新:滚动过程中触摸可将滚动条设置为页面底部
- 触摸事件的挖空事件绑定导致滚动问题
- 一页滚动iPad触摸滚动
- 触摸板滚动jQuery的问题
- 触摸拖动画布时滚动页面
- 在移动safari中有条件地阻止滚动/触摸事件
- iOS:-webkit溢出滚动:触摸并滚动顶部