Under Mobile Safari, is it possible to allow one absolutely positioned div
to scroll without allowing the entire page to bob up and down when it the scroll reaches the edges (elastically scrolling)?
Here is a minimal working example of the issue I'm facing:
<!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>
Solution:
$(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();
});
});