From: SassNinja Date: Thu, 1 Jun 2017 09:27:42 +0000 (+0200) Subject: Create relative scope detection & use the relative parent to adjust the calculation X-Git-Tag: v6.4.0-rc5~9^2~14 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f62f24fd006c96cf9e1ed23149edef3a5cf2e044;p=thirdparty%2Ffoundation%2Ffoundation-sites.git Create relative scope detection & use the relative parent to adjust the calculation If a nested off-canvas element is placed in a container with position:relative (mostly push/pull classes) this must be considered in the calculation of the fixed position emulation. To detect the relative scope I'm checking if the closest positioned element (offsetParent) has a left css value (typical for push/pull) or is affecting the top coord. The usage of adjustToLocalScope() is limited to nested elements because non-nested elements doesn't have that scope issue (due to position:fixed) --- diff --git a/js/foundation.offcanvas.js b/js/foundation.offcanvas.js index e993829a0..0a35104b5 100644 --- a/js/foundation.offcanvas.js +++ b/js/foundation.offcanvas.js @@ -33,6 +33,8 @@ class OffCanvas extends Plugin { this.position = 'left'; this.$content = $(); this.nested = !!(this.options.nested); + this.$relativeParent; + this.relativeScope = false; this._init(); this._events(); @@ -82,6 +84,13 @@ class OffCanvas extends Plugin { console.warn('Remember to use the nested option if using the content ID option!'); } + // For a nested element, find closest (relative) positioned element + if (this.nested) { + this.$relativeParent = this.$element.offsetParent(); + // Initial adjustment of the element according to local scope + this._adjustToLocalScope(); + } + this.$content.addClass(`has-transition-${this.options.transition}`); // Add an overlay over the content if necessary @@ -140,6 +149,7 @@ class OffCanvas extends Plugin { // Delay as timeout to prevent too many calls on resizing clearTimeout(resizeTimeout); resizeTimeout = setTimeout(() => { + this._adjustToLocalScope(); this._emulateFixedPosition(true); }, 250); }); @@ -182,6 +192,40 @@ class OffCanvas extends Plugin { } } + /** + * Adjust element's left position if relative parent is affecting local coords (left). + * This is required if using a nested element within a push/pull column. + * @private + */ + _adjustToLocalScope() { + if (this.nested) { + // Check if relative parent is affecting local coords + if (parseInt(this.$relativeParent.css('left')) > 0 || this.$relativeParent.offset().top > 0) { + this.relativeScope = true; + // Adjust element to local scope + let xOffset = Math.ceil(parseFloat(this.$relativeParent.css('left'))) * (-1); + switch (this.position) { + case 'top': + this.$element.css('left', xOffset).width($(window).width()); + break; + case 'bottom': + this.$element.css('left', xOffset).width($(window).width()); + break; + case 'left': + this.$element.css('left', xOffset); + break; + } + } else { + this.relativeScope = false; + // Reset adjustment + this.$element.css({ + 'left': '', + 'width': '' + }); + } + } + } + /** * Emulate fixed position for a nested off-canvas element by using fixed height and current document scrollTop. * This is necessary due to the transform property of the content that creates a new local coordinate system. @@ -192,17 +236,19 @@ class OffCanvas extends Plugin { if (this.nested === true) { + var topOffset = this.relativeScope ? this.$relativeParent.offset().top : 0; + if (this.position === 'top') { - this.$element.css('top', $(document).scrollTop()); + this.$element.css('top', $(document).scrollTop() - topOffset); } else if (this.position === 'bottom') { - this.$element.css('top', $(document).scrollTop() + $(window).height() - this.$element.outerHeight()); + this.$element.css('top', $(document).scrollTop() + $(window).height() - this.$element.outerHeight() - topOffset); } else { // left|right - this.$element.css('top', $(document).scrollTop()); + this.$element.css('top', $(document).scrollTop() - topOffset); if (resetHeight === true) { this.$element.height( $(window).height() ); @@ -309,6 +355,7 @@ class OffCanvas extends Plugin { this.$element.siblings('[data-off-canvas-content]').css('transition-duration', ''); } + this._adjustToLocalScope(); this._emulateFixedPosition(); /**