use data-chapter-id to replace id

This commit is contained in:
2026-03-03 14:59:27 +08:00
parent 3a8b6d9379
commit 870710d043
2 changed files with 10 additions and 7 deletions

View File

@@ -44,7 +44,7 @@
right: 30px; right: 30px;
bottom: 50px; bottom: 50px;
padding: 4px; padding: 4px;
background: white; background: lightblue;
border-radius: 8px; border-radius: 8px;
cursor: pointer; cursor: pointer;
} }

View File

@@ -5,7 +5,7 @@ import { Link } from "react-router";
import { CheckCircleOutlined } from "@ant-design/icons"; import { CheckCircleOutlined } from "@ant-design/icons";
import OpenInNewTab from "../../../node_modules/@material-icons/svg/svg/open_in_new/twotone.svg"; import OpenInNewTab from "../../../node_modules/@material-icons/svg/svg/open_in_new/twotone.svg";
import Icon from "../../components/Icon"; import Icon from "../../components/Icon";
import { useMemo, useState } from "react"; import { useMemo, useRef, useState } from "react";
import LocationSearchingTwotone from "../../../node_modules/@material-icons/svg/svg/location_searching/twotone.svg"; import LocationSearchingTwotone from "../../../node_modules/@material-icons/svg/svg/location_searching/twotone.svg";
export type VolumesListProps = { export type VolumesListProps = {
@@ -31,6 +31,7 @@ async function open_in_qidian(bookId: number, chapterId: number) {
} }
export default function VolumesList({ volumes, bookId, oneLine, current }: VolumesListProps) { export default function VolumesList({ volumes, bookId, oneLine, current }: VolumesListProps) {
const containerRef = useRef<HTMLDivElement>(null);
const currentVolumeId = useMemo(() => { const currentVolumeId = useMemo(() => {
if (!current) return null; if (!current) return null;
return volumes.find(v => v.chapters.some(ch => ch.id === current))?.id ?? null; return volumes.find(v => v.chapters.some(ch => ch.id === current))?.id ?? null;
@@ -39,12 +40,14 @@ export default function VolumesList({ volumes, bookId, oneLine, current }: Volum
const [activeKeys, setActiveKeys] = useState<string[]>([]); const [activeKeys, setActiveKeys] = useState<string[]>([]);
const scrollToCurrent = () => { const scrollToCurrent = () => {
if (!current || !currentVolumeId) return; if (!current || !currentVolumeId || !containerRef.current) return;
const findChapterEl = () => containerRef.current?.querySelector<HTMLElement>(`[data-chapter-id="${current}"]`);
if (!activeKeys.includes(currentVolumeId)) { if (!activeKeys.includes(currentVolumeId)) {
setActiveKeys(prev => [...prev, currentVolumeId]); setActiveKeys(prev => [...prev, currentVolumeId]);
function checkChapterInView() { function checkChapterInView() {
const el = document.getElementById(`chapter-${current}`); const el = findChapterEl();
if (el && el.offsetParent) { if (el && el.offsetParent) {
// Wait for the collapse animation to finish before scrolling // Wait for the collapse animation to finish before scrolling
setTimeout(() => { setTimeout(() => {
@@ -56,7 +59,7 @@ export default function VolumesList({ volumes, bookId, oneLine, current }: Volum
} }
setTimeout(checkChapterInView, 20); setTimeout(checkChapterInView, 20);
} else { } else {
const el = document.getElementById(`chapter-${current}`); const el = findChapterEl();
if (el) { if (el) {
el.scrollIntoView({ behavior: 'smooth', block: 'start' }); el.scrollIntoView({ behavior: 'smooth', block: 'start' });
} }
@@ -65,7 +68,7 @@ export default function VolumesList({ volumes, bookId, oneLine, current }: Volum
const items = useMemo<CollapseProps['items']>(() => volumes.map(v => { const items = useMemo<CollapseProps['items']>(() => volumes.map(v => {
const children = v.chapters.map(chapter => ( const children = v.chapters.map(chapter => (
<Flex className={oneLine ? styles.chone : styles.ch} key={chapter.id} id={`chapter-${chapter.id}`}> <Flex className={oneLine ? styles.chone : styles.ch} key={chapter.id} data-chapter-id={chapter.id}>
<Link to={`/qd/book/${bookId}/chapter/${chapter.id}`}>{chapter.name}</Link> <Link to={`/qd/book/${bookId}/chapter/${chapter.id}`}>{chapter.name}</Link>
<Flex className={styles.action}> <Flex className={styles.action}>
{chapter.isSaved && <CheckCircleOutlined className={styles.saved} />} {chapter.isSaved && <CheckCircleOutlined className={styles.saved} />}
@@ -87,7 +90,7 @@ export default function VolumesList({ volumes, bookId, oneLine, current }: Volum
</Flex> </Flex>
} }
}), [volumes, bookId, oneLine]); }), [volumes, bookId, oneLine]);
return (<div className={styles.c}> return (<div className={styles.c} ref={containerRef}>
<div className={styles.cl}><Collapse <div className={styles.cl}><Collapse
key={bookId} key={bookId}
activeKey={activeKeys} activeKey={activeKeys}