Javascript 在mobile safari中有条件地阻止滚动/触摸移动事件
iOS 5现在允许本机溢出:滚动支持 我想做的是禁用Javascript 在mobile safari中有条件地阻止滚动/触摸移动事件,javascript,jquery,webkit,cordova,mobile-safari,Javascript,Jquery,Webkit,Cordova,Mobile Safari,iOS 5现在允许本机溢出:滚动支持 我想做的是禁用touchmove事件,除了具有“scrollable”类或其子元素的元素 但我似乎无法让它发挥作用;以下是我一直在处理的问题: <html> <head> <style> .scrollable { height: 5em; overflow-y: scroll; -webkit-overflow-scrolling: touch; } </style> <script src="h
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>
.可滚动{
身高:5公分;
溢出y:滚动;
-webkit溢出滚动:触摸;
}
//似乎不起作用
var handleMove=函数(e){
if(!$(e.target).parents().andSelf().hasClass('scrollable')){
e、 预防默认值();
}
};
文件。添加的文件列表(“触摸移动”,handleMove,true);
如果拖动到此处,请不要滚动
如果拖动到这里,应该可以滚动
- 这里呢
- 这里呢
- 这里呢
- 这里呢
- 这里呢
- 这里呢
- 这里呢
- 这里呢
如果拖动到此处,请不要滚动
这里有一个(大部分)有效的解决方案,用于禁用除溢出元素外的所有元素的垂直滚动:
(咖啡脚本):
垂直滚动行为覆盖。
#
#这将禁用触摸设备页面上的垂直滚动,除非用户正在滚动
#在溢出的节点内。这需要对触摸事件进行一些处理。
#
#**注意:**如果用户试图在以下节点上滚动,则此代码将禁用反弹行为:
#已处于其上限或下限。
窗口$=$(窗口)
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()
我知道你问这个问题已经有一段时间了,但我也有同样的问题,我用你的代码作为解决问题的基础。谢谢你的灵感 (Javascript+jQuery)
var handleMove=函数(e){
var scrollable=false;
var items=$(e.target).parents();
$(项目)。每个(功能(i,o){
if($(o).hasClass(“可滚动”)){
可滚动=真;
}
});
如果(!可滚动)
e、 预防默认值();
};
文件。添加的文件列表(“触摸移动”,handleMove,true);
或者不太详细,但最终结果相同(credit J Griffiths):
var handleMove=函数(e){
if($(e.target).closest('.scrollable').length==0){e.preventDefault();}
}
文件。添加的文件列表(“触摸移动”,handleMove,true);
您还应该包括以下元标记
<meta name="viewport" content="width=device-width, initial-scale=1.0,
maximum-scale=1.0, user-scalable=no;" />
我尝试了Scott的答案,但在我的iphone iOS 5.1.1上不起作用 此外,如果你正在构建webClip应用程序,这一点尤为重要。天哪,我希望iOS 6能够允许使用视口标记来禁用自动反弹 下面我的版本和上面斯科特的答案一样有效(或无效),因为它基本上做了相同的事情 jQuery 1.7.2
$(document).bind("touchmove",function(e){
e.preventDefault();
});
$('.scrollable').bind("touchmove",function(e){
e.stopPropagation();
});
如果您在jquery document.ready事件中编写此代码,它将起作用
$('body').on('touchmove', function (e) {
if ($(e.target).closest("your_scrollable_div_selector").length == 0)
e.preventDefault();
});
基于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();
});
var initialY=null;
变量nodeStack=[];
变量$window=$(window);
$window.bind('touchstart',函数(e){
initialY=e.originalEvent.pageY;
nodeStack=$(e.target).parents().andSelf().filter(':not(body,html)').get().reverse();
nodeStack=nodeStack.map(函数(节点){
返回$(节点);
});
});
$window.bind('touchend touchcancel',函数(e){
initialY=null;
nodeStack=[];
});
$window.bind('touchmove',函数(e){
如果(!initialY){
e、 预防默认值();
}
变量方向=e.originalEvent.pageY-初始值;
对于(变量i=0;i节点高度){
//用户正在向上拖动内容,而元素已经向下滚动了一点。
var allowedUp=direction>0&&nodeScrollTop>0;
//用户向下拖动内容,而元素向上移动了一点。
var allowedDown=方向<0&&nodeScrollTop
我们可以
$(document).bind("touchmove",function(e){
e.preventDefault();
});
$('.scrollable').bind("touchmove",function(e){
e.stopPropagation();
});
$('body').on('touchmove', function (e) {
if ($(e.target).closest("your_scrollable_div_selector").length == 0)
e.preventDefault();
});
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();
});
document.ontouchstart = function(e){
e.preventDefault();
}