【发布时间】:2013-05-29 04:09:48
【问题描述】:
在 Mobile Safari 下,是否可以允许绝对定位的 div 在滚动到边缘时不让整个页面上下摆动(弹性滚动)?
这是我面临的问题的一个最小工作示例:
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
<meta name="apple-mobile-web-app-capable" content="yes" />
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
#a, #b {
position: absolute;
top: 0;
left: 0;
height: 100%;
padding: 10px;
overflow: auto;
}
#a {
width: 80px;
background: #f00;
}
#b {
background: #00f;
left: 80px;
width: 100%;
}
</style>
<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
<script>
function pdcb(e) {
e.preventDefault();
}
function npcb(e) {
e.stopPropagation();
}
$(document).on('touchstart touchmove', pdcb).
on('touchstart touchmove', '.scrollable', npcb);
</script>
</head>
<body>
<div id="a" class="scrollable">
This<br>
should<br>
be<br>
scrollable<br>
but<br>
not<br>
scroll<br>
the<br>
whole<br>
page<br>
This<br>
should<br>
be<br>
scrollable<br>
but<br>
not<br>
scroll<br>
the<br>
whole<br>
page<br>
This<br>
should<br>
be<br>
scrollable<br>
but<br>
not<br>
scroll<br>
the<br>
whole<br>
page<br>
This<br>
should<br>
be<br>
scrollable<br>
but<br>
not<br>
scroll<br>
the<br>
whole<br>
page<br>
This<br>
should<br>
be<br>
scrollable<br>
but<br>
not<br>
scroll<br>
the<br>
whole<br>
page<br>
</div>
<div id="b">
this should never scroll
</div>
</body>
</html>
解决方案:
$(document).on('touchmove', function(e) {
e.preventDefault();
}).ready(function() {
$(".scrollable").on('touchstart', function(e) {
this.allowUp = (this.scrollTop > 0);
this.allowDown = (this.scrollTop < this.scrollHeight - this.clientHeight);
this.prevTop = null;
this.prevBot = null;
this.lastY = e.originalEvent.pageY;
}).on('touchmove', function(e) {
var event = e.originalEvent;
var up = (event.pageY > this.lastY), down = !up;
this.lastY = event.pageY;
if ((up && this.allowUp) || (down && this.allowDown))
event.stopPropagation();
else
event.preventDefault();
});
});
【问题讨论】:
-
不,不是重复的。拥有两个
divs 会改变一切。 -
人们将其标记为重复 - 这不是重复的问题 - 引用的问题仅涉及完全阻止 iOS 中的原生动量滚动 - 这个问题/解决方案是关于在特定 div 上启用动量滚动同时阻止滚动整个页面。对于具有许多固定位置元素的 Web 应用很有用。
-
如果您希望它与动态添加的元素一起使用(例如在单页 JS 应用中),请将
$(".scrollable").on('touchstart', ...)替换为$(document.body).on('touchstart', '.scrollable', ...)。 -
当您已经在 div 的顶部时,此代码将阻止向上滚动。如果你将它用于 iOS 应用程序,它可能会感觉很糟糕。解决方法是将可滚动元素向下滚动 1px,因此可以使用反弹效果向上滚动:
$('.scrollable')[0].scrollTop = 1。您还可以处理结束滚动事件,并在 scrollTop 达到 0 时将其设置为 1,因此它永远不会被阻止向上滚动。 -
确保将
-webkit-overflow-scrolling: touch添加到.scrollable类的 CSS 声明中以获得漂亮的原生滚动。
标签: javascript html ios css mobile-safari