title: prevent full page scrolling iOS
body: <p>Under Mobile Safari, is it possible to allow one absolutely positioned <code>div</code> to scroll without allowing the entire page to bob up and down when it the scroll reaches the edges (elastically scrolling)?</p>
  
  <p>Here is a minimal working example of the issue I'm facing:</p>
  
  <pre><code>&lt;!doctype html&gt;
  &lt;html&gt;
  &lt;head&gt;
      &lt;meta charset="utf-8" /&gt;
      &lt;meta name="viewport" content="width=device-width, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"&gt;
      &lt;meta name="apple-mobile-web-app-capable" content="yes" /&gt;
      &lt;style&gt;
          * {
              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%;
          }
      &lt;/style&gt;
      &lt;script src="http://code.jquery.com/jquery-1.10.1.min.js"&gt;&lt;/script&gt;
      &lt;script&gt;
          function pdcb(e) {
              e.preventDefault();
          }
          function npcb(e) {
              e.stopPropagation();
          }
          $(document).on('touchstart touchmove', pdcb).
                      on('touchstart touchmove', '.scrollable', npcb);
      &lt;/script&gt;
  &lt;/head&gt;
  &lt;body&gt;
      &lt;div id="a" class="scrollable"&gt;
          This&lt;br&gt;
          should&lt;br&gt;
          be&lt;br&gt;
          scrollable&lt;br&gt;
          but&lt;br&gt;
          not&lt;br&gt;
          scroll&lt;br&gt;
          the&lt;br&gt;
          whole&lt;br&gt;
          page&lt;br&gt;
          This&lt;br&gt;
          should&lt;br&gt;
          be&lt;br&gt;
          scrollable&lt;br&gt;
          but&lt;br&gt;
          not&lt;br&gt;
          scroll&lt;br&gt;
          the&lt;br&gt;
          whole&lt;br&gt;
          page&lt;br&gt;
          This&lt;br&gt;
          should&lt;br&gt;
          be&lt;br&gt;
          scrollable&lt;br&gt;
          but&lt;br&gt;
          not&lt;br&gt;
          scroll&lt;br&gt;
          the&lt;br&gt;
          whole&lt;br&gt;
          page&lt;br&gt;
          This&lt;br&gt;
          should&lt;br&gt;
          be&lt;br&gt;
          scrollable&lt;br&gt;
          but&lt;br&gt;
          not&lt;br&gt;
          scroll&lt;br&gt;
          the&lt;br&gt;
          whole&lt;br&gt;
          page&lt;br&gt;
          This&lt;br&gt;
          should&lt;br&gt;
          be&lt;br&gt;
          scrollable&lt;br&gt;
          but&lt;br&gt;
          not&lt;br&gt;
          scroll&lt;br&gt;
          the&lt;br&gt;
          whole&lt;br&gt;
          page&lt;br&gt;
      &lt;/div&gt;
      &lt;div id="b"&gt;
          this should never scroll
      &lt;/div&gt;
  &lt;/body&gt;
  &lt;/html&gt;
  </code></pre>
  
  <hr>
  
  <p><strong>Solution:</strong></p>
  
  <pre><code>$(document).on('touchmove', function(e) {
      e.preventDefault();
  }).ready(function() {
      $(".scrollable").on('touchstart', function(e) {
          this.allowUp = (this.scrollTop &gt; 0);
          this.allowDown = (this.scrollTop &lt; 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 &gt; this.lastY), down = !up;
          this.lastY = event.pageY;
  
          if ((up &amp;&amp; this.allowUp) || (down &amp;&amp; this.allowDown))
              event.stopPropagation();
          else
              event.preventDefault();
      });
  });
  </code></pre>