diff --git a/public/vendor/exment/js/scroll-position-fix.js b/public/vendor/exment/js/scroll-position-fix.js new file mode 100644 index 000000000..1aa509387 --- /dev/null +++ b/public/vendor/exment/js/scroll-position-fix.js @@ -0,0 +1,119 @@ +/** + * Fix scroll position restore issue after browser back button + * For custom table list view in Exment + */ +(function() { + 'use strict'; + + const CLASSNAME_CUSTOM_VALUE_GRID = 'block_custom_value_grid'; + + // Save current scroll position + function saveCurrentScrollPosition() { + const scrollTop = $(window).scrollTop() || document.documentElement.scrollTop || document.body.scrollTop || 0; + + // Store in history state if available + if (window.history && window.history.replaceState) { + const currentState = window.history.state || {}; + currentState.scrollTop = scrollTop; + try { + window.history.replaceState(currentState, document.title); + } catch (e) { + console.warn('Failed to update history state:', e); + } + } + } + + // Restore scroll position from history state + function restoreScrollPosition() { + let scrollTop = 0; + + // Only restore from history state (for back button) + if (window.history && window.history.state && typeof window.history.state.scrollTop === 'number') { + scrollTop = window.history.state.scrollTop; + } + + if (scrollTop > 0) { + // Use setTimeout to ensure DOM is ready + setTimeout(function() { + window.scrollTo(0, scrollTop); + // Verify and retry if needed + setTimeout(function() { + const currentScroll = window.pageYOffset || document.documentElement.scrollTop; + if (Math.abs(currentScroll - scrollTop) > 50) { + window.scrollTo(0, scrollTop); + } + }, 100); + }, 0); + } + } + + // Initialize on document ready + $(function() { + // Prevent multiple initialization + if (window.exmentScrollFixInitialized) { + return; + } + window.exmentScrollFixInitialized = true; + + // Disable browser's default scroll restoration + if ('scrollRestoration' in history) { + history.scrollRestoration = 'manual'; + } + + restoreScrollPosition(); + + // Save scroll position periodically while scrolling + let scrollTimer; + $(window).on('scroll', function() { + clearTimeout(scrollTimer); + scrollTimer = setTimeout(function() { + // Only save if we're on a list page (grid view) + if ($('.' + CLASSNAME_CUSTOM_VALUE_GRID).length > 0) { + saveCurrentScrollPosition(); + } + }, 150); + }); + + // Save scroll position before leaving page + $(window).on('beforeunload', function() { + if ($('.' + CLASSNAME_CUSTOM_VALUE_GRID).length > 0) { + saveCurrentScrollPosition(); + } + }); + + // Handle pjax events + if ($.pjax) { + let isPjaxPopstate = false; + + $(document).on('pjax:popstate', function() { + isPjaxPopstate = true; + }); + + // Save scroll position before pjax request + $(document).on('pjax:send', function(event, xhr, options) { + if ($('.' + CLASSNAME_CUSTOM_VALUE_GRID).length > 0) { + saveCurrentScrollPosition(); + } + }); + + // Handle scroll position after pjax complete + $(document).on('pjax:end', function(event, xhr, options) { + if ($('.' + CLASSNAME_CUSTOM_VALUE_GRID).length > 0) { + if (isPjaxPopstate) { + // If it's a back/forward navigation, restore scroll + restoreScrollPosition(); + isPjaxPopstate = false; + } else { + // If it's a new navigation (pagination, sort, etc), scroll to top + window.scrollTo(0, 0); + } + } + }); + } + + // Save position when clicking on links in grid + $('.' + CLASSNAME_CUSTOM_VALUE_GRID).on('click', 'a', function() { + saveCurrentScrollPosition(); + }); + }); +})(); diff --git a/src/Middleware/Bootstrap.php b/src/Middleware/Bootstrap.php index 4c57caa8d..507ba13d0 100644 --- a/src/Middleware/Bootstrap.php +++ b/src/Middleware/Bootstrap.php @@ -77,6 +77,7 @@ protected function setCssJs(Request $request, \Closure $next) 'vendor/exment/jstree/jstree.min.js', 'vendor/exment/js/common_all.js', 'vendor/exment/js/common.js', + 'vendor/exment/js/scroll-position-fix.js', 'vendor/exment/js/search.js', 'vendor/exment/js/calc.js', 'vendor/exment/js/notify_navbar.js',