diff --git a/code/websites/pokedex.online/src/views/GamemasterExplorer.vue b/code/websites/pokedex.online/src/views/GamemasterExplorer.vue index 237ba9a..3784bda 100644 --- a/code/websites/pokedex.online/src/views/GamemasterExplorer.vue +++ b/code/websites/pokedex.online/src/views/GamemasterExplorer.vue @@ -758,43 +758,50 @@ function scrollToResult() { })); } - // Retry logic for virtual scroller rendering - const attemptScroll = (attempt = 0) => { - const lineElement = document.querySelector(`[data-line="${lineNumber}"]`); + // Use virtual scroller API if available (for large files) + if (virtualScroller.value && displayLines.value.length > 1000) { + nextTick(() => { + virtualScroller.value.scrollToItem(lineIndex); + }); + } else { + // Fallback for non-virtual scrolled content + const attemptScroll = (attempt = 0) => { + const lineElement = document.querySelector(`[data-line="${lineNumber}"]`); - if (lineElement) { - // Scroll only within the container, not the whole page - const container = lineElement.closest('.scroller, .lines-container'); - if (container) { - // Get element's position relative to the container - const elementOffsetTop = lineElement.offsetTop; - const containerHeight = container.clientHeight; - const elementHeight = lineElement.offsetHeight; + if (lineElement) { + // Scroll only within the container, not the whole page + const container = lineElement.closest('.scroller, .lines-container'); + if (container) { + // Get element's position relative to the container + const elementOffsetTop = lineElement.offsetTop; + const containerHeight = container.clientHeight; + const elementHeight = lineElement.offsetHeight; - // Calculate scroll position to center element in container - const scrollTo = - elementOffsetTop - containerHeight / 2 + elementHeight / 2; - container.scrollTo({ top: scrollTo, behavior: 'smooth' }); + // Calculate scroll position to center element in container + const scrollTo = + elementOffsetTop - containerHeight / 2 + elementHeight / 2; + container.scrollTo({ top: scrollTo, behavior: 'smooth' }); + } + return true; + } else if (attempt < 3) { + // Virtual scroller may not have rendered yet, try again + setTimeout(() => attemptScroll(attempt + 1), 50); + return false; + } else { + // Fallback: scroll container to approximate position + const container = document.querySelector('.scroller, .lines-container'); + if (container) { + const estimatedScroll = + (lineIndex / fileLines.value.length) * + (container.scrollHeight - container.clientHeight); + container.scrollTop = estimatedScroll; + } + return false; } - return true; - } else if (attempt < 3) { - // Virtual scroller may not have rendered yet, try again - setTimeout(() => attemptScroll(attempt + 1), 50); - return false; - } else { - // Fallback: scroll container to approximate position - const container = document.querySelector('.scroller, .lines-container'); - if (container) { - const estimatedScroll = - (lineIndex / fileLines.value.length) * - (container.scrollHeight - container.clientHeight); - container.scrollTop = estimatedScroll; - } - return false; - } - }; + }; - attemptScroll(); + attemptScroll(); + } } function applyHistoryItem(item) {