]> git.ipfire.org Git - thirdparty/foundation/foundation-sites.git/commitdiff
Enable scrolling within offcanvas panel on iOS even when body scrolling disabled 9707/head
authorKevin Ball <kmball11@gmail.com>
Thu, 26 Jan 2017 23:41:30 +0000 (15:41 -0800)
committerKevin Ball <kmball11@gmail.com>
Thu, 26 Jan 2017 23:41:39 +0000 (15:41 -0800)
js/foundation.offcanvas.js
test/visual/offcanvas/all-options.html

index fb5c2b1f11b8ee1d9b07bea12f35f2f72af488fd..71dc45c2d7f67d5b5748fb9005d2798d56dc501f 100644 (file)
@@ -147,7 +147,41 @@ class OffCanvas {
    * @private
    */
   _stopScrolling(event) {
-       return false;
+    return false;
+  }
+
+  // Taken and adapted from http://stackoverflow.com/questions/16889447/prevent-full-page-scrolling-ios
+  // Only really works for y, not sure how to extend to x or if we need to.
+  _recordScrollable(event) {
+    let elem = this; // called from event handler context with this as elem
+
+     // If the element is scrollable (content overflows), then...
+    if (elem.scrollHeight !== elem.clientHeight) {
+      // If we're at the top, scroll down one pixel to allow scrolling up
+      if (elem.scrollTop === 0) {
+        elem.scrollTop = 1;
+      }
+      // If we're at the bottom, scroll up one pixel to allow scrolling down
+      if (elem.scrollTop === elem.scrollHeight - elem.clientHeight) {
+        elem.scrollTop = elem.scrollHeight - elem.clientHeight - 1;
+      }
+    }
+    elem.allowUp = elem.scrollTop > 0;
+    elem.allowDown = elem.scrollTop < (elem.scrollHeight - elem.clientHeight);
+    elem.lastY = event.originalEvent.pageY;
+  }
+
+  _stopScrollPropagation(event) {
+    let elem = this; // called from event handler context with this as elem
+    let up = event.pageY < elem.lastY;
+    let down = !up;
+    elem.lastY = event.pageY;
+
+    if((up && elem.allowUp) || (down && elem.allowDown)) {
+      event.stopPropagation();
+    } else {
+      event.preventDefault();
+    }
   }
 
   /**
@@ -184,6 +218,8 @@ class OffCanvas {
     // If `contentScroll` is set to false, add class and disable scrolling on touch devices.
     if (this.options.contentScroll === false) {
       $('body').addClass('is-off-canvas-open').on('touchmove', this._stopScrolling);
+      this.$element.on('touchstart', this._recordScrollable);
+      this.$element.on('touchmove', this._stopScrollPropagation);
     }
 
     if (this.options.contentOverlay === true) {
@@ -234,6 +270,8 @@ class OffCanvas {
     // If `contentScroll` is set to false, remove class and re-enable scrolling on touch devices.
     if (this.options.contentScroll === false) {
       $('body').removeClass('is-off-canvas-open').off('touchmove', this._stopScrolling);
+      this.$element.off('touchstart', this._recordScrollable);
+      this.$element.off('touchmove', this._stopScrollPropagation);
     }
 
     if (this.options.contentOverlay === true) {
index ddfafe19a5aa82d3f1ced63eed36683bf76ecdf4..7cafe1b031444cbe7e3381ba78c38108bb7f77e8 100644 (file)
           <span aria-hidden="true">&times;</span>
         </button>
         <h3>This is a left off-canvas panel with content scroll disabled.</h3>
+        <p>The content <b>Inside</b> the panel should still be scrollable.</p>
+        <p>The content <b>Inside</b> the panel should still be scrollable.</p>
+        <p>The content <b>Inside</b> the panel should still be scrollable.</p>
+        <p>The content <b>Inside</b> the panel should still be scrollable.</p>
+        <p>The content <b>Inside</b> the panel should still be scrollable.</p>
+        <p>The content <b>Inside</b> the panel should still be scrollable.</p>
+        <p>The content <b>Inside</b> the panel should still be scrollable.</p>
+        <p>The content <b>Inside</b> the panel should still be scrollable.</p>
+        <p>The content <b>Inside</b> the panel should still be scrollable.</p>
+        <p>The content <b>Inside</b> the panel should still be scrollable.</p>
+        <p>The content <b>Inside</b> the panel should still be scrollable.</p>
+        <p>The content <b>Inside</b> the panel should still be scrollable.</p>
+        <p>The content <b>Inside</b> the panel should still be scrollable.</p>
+        <p>The content <b>Inside</b> the panel should still be scrollable.</p>
+        <p>The content <b>Inside</b> the panel should still be scrollable.</p>
+        <p>The content <b>Inside</b> the panel should still be scrollable.</p>
+        <p>The content <b>Inside</b> the panel should still be scrollable.</p>
+        <p>The content <b>Inside</b> the panel should still be scrollable.</p>
+        <p>The content <b>Inside</b> the panel should still be scrollable.</p>
+        <p>The content <b>Inside</b> the panel should still be scrollable.</p>
+        <p>The content <b>Inside</b> the panel should still be scrollable.</p>
+        <p>The content <b>Inside</b> the panel should still be scrollable.</p>
+        <p>The content <b>Inside</b> the panel should still be scrollable.</p>
+        <p>The content <b>Inside</b> the panel should still be scrollable.</p>
       </div>
 
       <div class="off-canvas position-left" id="noOverlay" data-off-canvas data-content-overlay="false">