Skip to content

Instantly share code, notes, and snippets.

@mattsahr
Created November 17, 2011 02:47
Show Gist options
  • Star 18 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save mattsahr/1372229 to your computer and use it in GitHub Desktop.
Save mattsahr/1372229 to your computer and use it in GitHub Desktop.
IOS Webkit - native internal scroll - a fix for the document page-top-bounce
<!DOCTYPE html>
<html>
<!-- NOTES
Demo - uses IOS native scroll available in IOS5, but sidestep the document-bounce behavior. Tested on iPad 1, using IOS 5.1.
This approach uses a set of 3 nested divs.
OuterDiv -- fixed height, width, overflow-scrolling: touch;
MiddleDiv -- fixed height width, overflow-scrolling: touch; fits inside OuterDiv
InnerDiv -- fixed height width, bigger than MiddleDiv, so it kicks in the overflow behavior
This particular example does the triple-nested trick twice.
The inner 3-wrapper-set uses no javascript
(height and width are explicit CSS declarations).
The outside 3-wrapper-set uses javascript to fetch
the document height, so that it can be full-window-size.
This approach allows native internal scrolls AND reaps
the benefits of killing page-bounce for the overall document.
-->
<head>
<meta charset="utf-8" />
<title>ios webkit native scroll test</title>
<style>
body,ul,li { padding:0; margin:0; border:0; }
body { font-family: Verdana, Helvetica, Arial, sans-serif; }
#divHead { top:0; }
#divFoot { bottom:0; }
#divHead, #divFoot {
position:fixed;
width:100%;
z-index:2;
left:0;
background-color:#c27b00;
font-size:20px;
text-align:center;
color:#f3f3f3;
font-weight:bold;
line-height:45px;
height:48px;
padding:0;
}
#pageOuter, #pageMiddle {
position:absolute;
width:100%;
top:0px;
left:0px;
padding:0px;
-webkit-overflow-scrolling: touch;
overflow:auto;
}
#pageInner {
position:absolute;
width:100%;
top:0px;
left:0px;
padding:0px;
}
#divOuter {
padding:10px;
border: 2px solid #0055bb;
position:absolute;
top:60px;
left:30px;
height:500px;
width: 400px;
-webkit-overflow-scrolling: touch;
overflow:auto;
background:#ffffff;
}
#divMiddle {
z-index:1;
width:100%;
border: solid 2px #aa8800;
position:absolute;
height:500px;
width: 400px;
background:#ffffff;
-webkit-overflow-scrolling: touch;
overflow:auto;
}
#divInner {
position:absolute;
z-index:1;
top:0;
padding:0;
width: 900px;
}
ul {
list-style:none;
padding:0;
margin:0;
width:100%;
text-align:left;
}
ul li {
padding:0 10px 0px 40px;
height:120px;
line-height:120px;
border-bottom:1px solid #ccc;
border-top:1px solid #fff;
background-color:#fafafa;
font-size:26px;
}
</style>
</head>
<body>
<div id="divHead">
Web App Template
</div>
<div id="pageOuter">
<div id="pageMiddle">
<div id="pageInner">
<div id="divOuter">
<div id="divMiddle">
<div id="divInner">
<ul>
<li> v9 ... somewhat random filler random somewhat filler </li>
<li>More Stuff somewhat random filler som random filler </li>
<li>Big Stuff somewhat random filler somewhat, random </li>
<li>Small Stuff somewhat random random random</li>
<li>Geek Stuff somewhat random filler somewhat</li>
<li>Nerd Stuff somewhat filler somewhat, somwhat random</li>
<li>Fast Stuff somewhat random filler somewhat, somwhat random</li>
<li>Slow Stuff somewhat random filler somwhat random</li>
<li>Good Stuff somewhat random filler somewhat, somwhat random</li>
<li>Bad Stuff somewhat random filler somewhat, somwhat random</li>
<li>Your Stuff somewhat random filler somewhat, random</li>
<li>My Stuff random filler somewhat, somwhat random</li>
</ul>
</div> <!-- END // div id="divInner" -->
</div> <!-- END // div id="divMiddle" -->
</div> <!-- END // div id="divOuter" -->
</div> <!-- END // div id="pageInner" -->
</div> <!-- END // div id="pageMiddle" -->
</div> <!-- END // div id="pageOuter" -->
<div id="divFoot">
Some Footer Content
</div>
<script type="text/javascript" charset="utf-8">
var body = document.body, html = document.documentElement;
var height = Math.max( body.scrollHeight, body.offsetHeight,
html.clientHeight, html.scrollHeight, html.offsetHeight );
document.getElementById('pageOuter').style.height = height+'px';
document.getElementById('pageMiddle').style.height = height+'px';
height=height+1;
document.getElementById('pageInner').style.height = height+'px';
</script>
</body>
</html>
@pward123
Copy link

Thanks! This helped me out quite a bit. FYI, you still end up with the bounce if pageInner ends up smaller than pageMiddle.

The following fixes the problem above for me. However, in my case, the width of pageOuter, pageMiddle and pageInner are all forced to be the same. If you need to scroll right/left, you'll have to take that into account when discarding the touchMove event.

    $('.pageOuter').on('touchmove', function( e ){
        var middleHeight = $('.pageMiddle').height(),
            innertHeight = $('.pageInner').height();

        if (middleHeight >= innerHeight) {
            e.preventDefault();             
        }
    });

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment