]> git.ipfire.org Git - thirdparty/foundation/foundation-sites.git/commitdiff
Merge pull request #9707 from zurb/offcanvas-scrolling-is-9696
authorKevin Ball <kmball11@gmail.com>
Fri, 3 Feb 2017 21:16:31 +0000 (13:16 -0800)
committerKevin Ball <kmball11@gmail.com>
Fri, 3 Feb 2017 21:20:52 +0000 (13:20 -0800)
Enable scrolling within offcanvas panel on iOS even when body scrolli…

js/foundation.offcanvas.js
test/visual/offcanvas/all-options.html

index 2121ca0c8b752b5bcdfd6328125ab49eb6896732..c6d7b5bde17023a6c9b0052666010300525096bc 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) {
@@ -229,6 +265,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">