mirror of
https://github.com/GitbookIO/gitbook.git
synced 2026-09-21 01:53:26 +00:00
Support scroll to text fragment (#4060)
This commit is contained in:
@@ -6,16 +6,33 @@ import { useHash } from './useHash';
|
||||
import { usePrevious } from './usePrevious';
|
||||
|
||||
/**
|
||||
* Scroll the page to the hash or reset scroll to the top.
|
||||
* Only triggered while navigating in the app, not for initial load.
|
||||
* Handles scroll behavior when the URL hash changes during client-side navigation.
|
||||
*
|
||||
* - If a hash is present, scrolls smoothly to the corresponding element.
|
||||
* - If the hash is removed, scrolls back to the top of the page.
|
||||
*
|
||||
* This hook only reacts to in-app navigations. It avoids interfering with:
|
||||
* - The browser's native hash scrolling on initial load
|
||||
* - Scroll-to-text fragments (which cannot be reliably detected)
|
||||
*/
|
||||
export function useScrollPage() {
|
||||
const hash = useHash();
|
||||
const previousHash = usePrevious(hash);
|
||||
|
||||
React.useEffect(() => {
|
||||
// If there's no hash:
|
||||
// - On initial load, `previousHash` is undefined.
|
||||
// We do nothing to avoid overriding:
|
||||
// • Native browser hash scrolling
|
||||
// • Scroll-to-text fragments (undetectable)
|
||||
if (previousHash === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (hash) {
|
||||
if (previousHash !== undefined && previousHash !== hash) {
|
||||
// Only scroll if this is not the initial render
|
||||
// and the hash actually changed.
|
||||
if (previousHash !== hash) {
|
||||
const element = document.getElementById(hash);
|
||||
if (element) {
|
||||
element.scrollIntoView({
|
||||
@@ -27,13 +44,8 @@ export function useScrollPage() {
|
||||
return;
|
||||
}
|
||||
|
||||
// On initial load `previousHash` can be undefined,
|
||||
// but if the URL contains a fragment (hash),
|
||||
// we don't override native anchor scrolling
|
||||
if (!previousHash && window.location.hash) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If the hash was removed during navigation,
|
||||
// reset scroll position to the top.
|
||||
window.scrollTo(0, 0);
|
||||
}, [hash, previousHash]);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user