]> git.ipfire.org Git - thirdparty/foundation/foundation-sites.git/commitdiff
Create relative scope detection & use the relative parent to adjust the calculation
authorSassNinja <kai.falkowski@gmail.com>
Thu, 1 Jun 2017 09:27:42 +0000 (11:27 +0200)
committerSassNinja <kai.falkowski@gmail.com>
Thu, 1 Jun 2017 09:27:42 +0000 (11:27 +0200)
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)

js/foundation.offcanvas.js

index e993829a0c1dc8cd3d6c244f59472b16aa304e3b..0a35104b54b150748ecffa230bb50b76c63650a0 100644 (file)
@@ -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();
 
     /**