From: Kevin Ball Date: Thu, 26 Jan 2017 23:41:30 +0000 (-0800) Subject: Enable scrolling within offcanvas panel on iOS even when body scrolling disabled X-Git-Tag: 6.3.1~9^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=refs%2Fpull%2F9707%2Fhead;p=thirdparty%2Ffoundation%2Ffoundation-sites.git Enable scrolling within offcanvas panel on iOS even when body scrolling disabled --- diff --git a/js/foundation.offcanvas.js b/js/foundation.offcanvas.js index fb5c2b1f1..71dc45c2d 100644 --- a/js/foundation.offcanvas.js +++ b/js/foundation.offcanvas.js @@ -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) { diff --git a/test/visual/offcanvas/all-options.html b/test/visual/offcanvas/all-options.html index ddfafe19a..7cafe1b03 100644 --- a/test/visual/offcanvas/all-options.html +++ b/test/visual/offcanvas/all-options.html @@ -87,6 +87,30 @@

This is a left off-canvas panel with content scroll disabled.

+

The content Inside the panel should still be scrollable.

+

The content Inside the panel should still be scrollable.

+

The content Inside the panel should still be scrollable.

+

The content Inside the panel should still be scrollable.

+

The content Inside the panel should still be scrollable.

+

The content Inside the panel should still be scrollable.

+

The content Inside the panel should still be scrollable.

+

The content Inside the panel should still be scrollable.

+

The content Inside the panel should still be scrollable.

+

The content Inside the panel should still be scrollable.

+

The content Inside the panel should still be scrollable.

+

The content Inside the panel should still be scrollable.

+

The content Inside the panel should still be scrollable.

+

The content Inside the panel should still be scrollable.

+

The content Inside the panel should still be scrollable.

+

The content Inside the panel should still be scrollable.

+

The content Inside the panel should still be scrollable.

+

The content Inside the panel should still be scrollable.

+

The content Inside the panel should still be scrollable.

+

The content Inside the panel should still be scrollable.

+

The content Inside the panel should still be scrollable.

+

The content Inside the panel should still be scrollable.

+

The content Inside the panel should still be scrollable.

+

The content Inside the panel should still be scrollable.