frontblocks-sticky-column-option.js
2 months ago
frontblocks-sticky-column-option.jsx
2 months ago
frontblocks-sticky-column.css
2 months ago
frontblocks-sticky-column.js
2 months ago
frontblocks-sticky-column.js
58 lines
| 1 | (function() { |
| 2 | 'use strict'; |
| 3 | |
| 4 | document.addEventListener('DOMContentLoaded', function() { |
| 5 | initStickyColumns(); |
| 6 | }); |
| 7 | |
| 8 | window.addEventListener('load', function() { |
| 9 | initStickyColumns(); |
| 10 | }); |
| 11 | |
| 12 | function initStickyColumns() { |
| 13 | const stickyWrappers = document.querySelectorAll('.frontblocks-sticky-wrapper[data-sticky-enabled="true"]'); |
| 14 | |
| 15 | stickyWrappers.forEach(function(wrapper) { |
| 16 | const stickyOffset = parseInt(wrapper.getAttribute('data-sticky-offset')) || 0; |
| 17 | const stickyColumnIndex = parseInt(wrapper.getAttribute('data-sticky-column-index')) || 0; |
| 18 | |
| 19 | // Only direct children to avoid matching nested blocks. |
| 20 | const columns = wrapper.querySelectorAll(':scope > .gb-grid-column, :scope > .wp-block-column'); |
| 21 | |
| 22 | if (columns.length <= stickyColumnIndex) { |
| 23 | return; |
| 24 | } |
| 25 | |
| 26 | const column = columns[stickyColumnIndex]; |
| 27 | |
| 28 | // For GenerateBlocks, apply sticky to the inner .gb-container (it's not the flex item). |
| 29 | // For native wp-block-column, create an inner wrapper — applying sticky directly to |
| 30 | // a flex item is unreliable across browsers; sticky works best on a descendant of the flex item. |
| 31 | let stickyTarget = column.querySelector('.gb-container'); |
| 32 | |
| 33 | if (!stickyTarget) { |
| 34 | stickyTarget = document.createElement('div'); |
| 35 | stickyTarget.className = 'frontblocks-sticky-inner'; |
| 36 | while (column.firstChild) { |
| 37 | stickyTarget.appendChild(column.firstChild); |
| 38 | } |
| 39 | column.appendChild(stickyTarget); |
| 40 | } |
| 41 | |
| 42 | // Apply sticky via inline styles — avoids specificity wars with WP-generated .wp-container-* rules. |
| 43 | stickyTarget.style.position = 'sticky'; |
| 44 | stickyTarget.style.top = stickyOffset + 'px'; |
| 45 | stickyTarget.style.zIndex = '100'; |
| 46 | |
| 47 | // flex-start needed so the column has natural height; without it position:sticky has no room to scroll. |
| 48 | if (wrapper.classList.contains('wp-block-columns')) { |
| 49 | wrapper.style.alignItems = 'flex-start'; |
| 50 | } |
| 51 | }); |
| 52 | } |
| 53 | |
| 54 | if (typeof wp !== 'undefined' && wp.hooks) { |
| 55 | wp.hooks.addAction('frontblocks/sticky-columns-reinit', 'frontblocks/sticky-columns', initStickyColumns); |
| 56 | } |
| 57 | |
| 58 | })(); |