From e539439d8f3dc995cde963002f5870a2104fee06 Mon Sep 17 00:00:00 2001 From: Yourz Date: Wed, 7 Jan 2026 11:16:57 +0800 Subject: [PATCH] fix: 3rd level nodes scroll stuck --- src/components/common/TreeExplorer.vue | 33 ++++++++++++-------------- 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/src/components/common/TreeExplorer.vue b/src/components/common/TreeExplorer.vue index 6dd0f7d02..cd7d46f4e 100644 --- a/src/components/common/TreeExplorer.vue +++ b/src/components/common/TreeExplorer.vue @@ -120,6 +120,7 @@ const viewRows = computed(() => const bufferRows = computed(() => Math.max(1, Math.floor(viewRows.value / 3))) const windowSize = computed(() => viewRows.value + bufferRows.value * 2) +// Compute window ranges for all nodes const parentWindowRanges = computed>(() => { if (!containerHeight.value || !renderedRoot.value.children) { return {} @@ -130,7 +131,6 @@ const parentWindowRanges = computed>(() => { const scrollBottom = scrollTop + containerHeight.value const nodePositions = new Map() - const nodeEndPositions = new Map() let currentPos = 0 const calculatePositions = (node: RenderedTreeExplorerNode): number => { @@ -144,7 +144,6 @@ const parentWindowRanges = computed>(() => { } } - nodeEndPositions.set(node.key, currentPos) return currentPos } @@ -152,29 +151,32 @@ const parentWindowRanges = computed>(() => { currentPos = calculatePositions(child) } - const computeNodeWindow = (node: RenderedTreeExplorerNode) => { + const computeNodeWindow = (node: RenderedTreeExplorerNode): void => { if (!node.children || node.leaf) return const isExpanded = expandedKeys.value?.[node.key] ?? false if (!isExpanded) return - const nodeStart = nodePositions.get(node.key) ?? 0 - const childrenStart = nodeStart + DEFAULT_NODE_HEIGHT const totalChildren = node.children.length - if (totalChildren === 0) return - const childrenEnd = nodeEndPositions.get(node.key) ?? childrenStart + for (const child of node.children) { + computeNodeWindow(child) + } - const relativeScrollTop = Math.max(0, scrollTop - childrenStart) - const relativeScrollBottom = Math.max(0, scrollBottom - childrenStart) + const nodeStart = nodePositions.get(node.key) ?? 0 + const childrenStart = nodeStart + DEFAULT_NODE_HEIGHT + const estimatedChildrenEnd = childrenStart + totalChildren * DEFAULT_NODE_HEIGHT const bufferHeight = bufferRows.value * DEFAULT_NODE_HEIGHT - const childrenAreaVisible = - childrenStart <= scrollBottom + bufferHeight && - childrenEnd >= scrollTop - bufferHeight + const isInView = + estimatedChildrenEnd >= scrollTop - bufferHeight && + childrenStart <= scrollBottom + bufferHeight + + if (isInView) { + const relativeScrollTop = Math.max(0, scrollTop - childrenStart) + const relativeScrollBottom = Math.max(0, scrollBottom - childrenStart) - if (childrenAreaVisible) { const fromRow = Math.max( 0, Math.floor(relativeScrollTop / DEFAULT_NODE_HEIGHT) - bufferRows.value @@ -192,16 +194,11 @@ const parentWindowRanges = computed>(() => { ) } } else { - // Node is outside visible range, show initial window ranges[node.key] = createInitialWindowRange( totalChildren, windowSize.value ) } - - for (const child of node.children) { - computeNodeWindow(child) - } } for (const child of renderedRoot.value.children) {