返回 DeepSeek-Reasonix
listReadAnchor.ts
根目录 / desktop / frontend / src / lib / listReadAnchor.ts
1 export type ListReadAnchor = { scroller: HTMLElement; row: HTMLElement; key: string; top: number; scrollTop: number };
2
3 export function captureListReadAnchor(root: HTMLElement | null): ListReadAnchor | undefined {
4 if (!root) return;
5 let scroller: HTMLElement | null = root.querySelector(".project-tree__list") ?? root;
6 while (scroller && !(scroller.scrollHeight > scroller.clientHeight && /(auto|scroll)/.test(getComputedStyle(scroller).overflowY))) scroller = scroller.parentElement;
7 if (!scroller) return;
8 const bounds = scroller.getBoundingClientRect();
9 const row = Array.from(root.querySelectorAll<HTMLElement>("[data-topic-open-key]")).find((row) => {
10 const box = row.getBoundingClientRect(); return box.bottom > bounds.top && box.top < bounds.bottom;
11 });
12 if (row) return { scroller, row, key: row.dataset.topicOpenKey ?? "", top: row.getBoundingClientRect().top, scrollTop: scroller.scrollTop };
13 }
14
15 export function restoreListReadAnchor(root: HTMLElement | null, anchor?: ListReadAnchor): void {
16 if (!root || !anchor || !anchor.scroller.isConnected || anchor.scroller.scrollTop !== anchor.scrollTop) return;
17 const row = anchor.row.isConnected ? anchor.row : Array.from(root.querySelectorAll<HTMLElement>("[data-topic-open-key]")).find((row) => row.dataset.topicOpenKey === anchor.key);
18 if (row) anchor.scroller.scrollTop += row.getBoundingClientRect().top - anchor.top;
19 }
20
20 lines TYPESCRIPT