From fbc67175ae31e9b41b760dcaaa2050fe4067bc10 Mon Sep 17 00:00:00 2001 From: hypercross Date: Sun, 22 Mar 2026 00:57:35 +0800 Subject: [PATCH] fix: scrolling --- src/App.tsx | 9 ++++++--- src/components/Article.tsx | 30 +++++++++++++++++++++++++++++- 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index 046ef15..799e08c 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -42,9 +42,12 @@ const App: Component = () => {

TTRPG Tools

-
-
-
+ {/* fill th rest of the space*/} +
+
+
+
+
); }; diff --git a/src/components/Article.tsx b/src/components/Article.tsx index f09f88e..c605e1b 100644 --- a/src/components/Article.tsx +++ b/src/components/Article.tsx @@ -1,9 +1,10 @@ -import { Component, createSignal, createEffect, onCleanup, Show, createResource, createMemo } from 'solid-js'; +import { Component, createEffect, onCleanup, Show, createResource, createMemo } from 'solid-js'; import { parseMarkdown } from '../markdown'; import { extractSection } from '../data-loader'; import mermaid from 'mermaid'; import {getIndexedData} from "../data-loader/file-index"; import { resolvePath } from './utils/path'; +import { useLocation } from '@solidjs/router'; export interface ArticleProps { src: string; @@ -12,6 +13,7 @@ export interface ArticleProps { onLoaded?: () => void; onError?: (error: Error) => void; class?: string; // 额外的 class 用于样式控制 + scrollToHash?: boolean; // 是否自动滚动到 hash } async function fetchArticleContent(params: { src: string; section?: string }): Promise { @@ -20,11 +22,34 @@ async function fetchArticleContent(params: { src: string; section?: string }): P return params.section ? extractSection(text, params.section) : text; } +/** + * 滚动到指定的 hash 元素 + */ +function scrollToHash(hash: string) { + if (!hash) return; + // 移除 # 前缀 + const id = hash.startsWith('#') ? hash.slice(1) : hash; + if (!id) return; + + // 使用 decodeURIComponent 解码 ID(处理中文等特殊字符) + const decodedId = decodeURIComponent(id); + + // 尝试查找元素 + const element = document.getElementById(decodedId); + if (element) { + // 使用 scrollIntoView 滚动到元素 + element.scrollIntoView({ behavior: 'instant', block: 'start' }); + return true; + } + return false; +} + /** * Article 组件 * 用于将特定 src 位置的 md 文件显示为 markdown 文章 */ export const Article: Component = (props) => { + const location = useLocation(); const [content, { refetch }] = createResource( () => ({ src: props.src, section: props.section }), fetchArticleContent @@ -42,6 +67,9 @@ export const Article: Component = (props) => { props.onLoaded?.(); // 内容加载完成后,渲染 mermaid 图表 void mermaid.run(); + + // 内容渲染后检查 hash 并滚动 + scrollToHash(location.hash); } });