fix(@vben/layouts): scope hash targets to layout
This commit is contained in:
@@ -116,6 +116,31 @@ describe('useLayoutScroll', () => {
|
||||
expect(element.scrollTo).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should ignore matching hash targets outside the layout', async () => {
|
||||
window.history.replaceState({ position: 0 }, '');
|
||||
const hostTarget = document.createElement('div');
|
||||
hostTarget.id = 'section';
|
||||
hostTarget.scrollIntoView = vi.fn();
|
||||
document.body.append(hostTarget);
|
||||
const element = createScrollElement();
|
||||
const layoutTarget = document.createElement('div');
|
||||
layoutTarget.id = 'section';
|
||||
layoutTarget.scrollIntoView = vi.fn();
|
||||
element.append(layoutTarget);
|
||||
const routerMock = createRouterMock();
|
||||
mountLayoutScroll(routerMock.router);
|
||||
const { afterHook } = routerMock.getHooks();
|
||||
|
||||
window.history.replaceState({ position: 1 }, '');
|
||||
await runAfterHook(afterHook, '#section');
|
||||
|
||||
expect(layoutTarget.scrollIntoView).toHaveBeenCalledWith({
|
||||
behavior: 'smooth',
|
||||
block: 'start',
|
||||
});
|
||||
expect(hostTarget.scrollIntoView).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should restore a saved position on history navigation', async () => {
|
||||
window.history.replaceState({ position: 0 }, '');
|
||||
const element = createScrollElement();
|
||||
|
||||
@@ -16,18 +16,18 @@ function getHistoryPosition() {
|
||||
return typeof position === 'number' ? position : undefined;
|
||||
}
|
||||
|
||||
function getHashTarget(hash: string) {
|
||||
if (typeof document === 'undefined' || !hash.startsWith('#')) {
|
||||
function getHashTarget(scrollElement: HTMLElement, hash: string) {
|
||||
if (!hash.startsWith('#')) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const id = hash.slice(1);
|
||||
try {
|
||||
return document.querySelector<HTMLElement>(
|
||||
return scrollElement.querySelector<HTMLElement>(
|
||||
`#${CSS.escape(decodeURIComponent(id))}`,
|
||||
);
|
||||
} catch {
|
||||
return document.querySelector<HTMLElement>(`#${CSS.escape(id)}`);
|
||||
return scrollElement.querySelector<HTMLElement>(`#${CSS.escape(id)}`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,7 +62,7 @@ export function useLayoutScroll(router: LayoutScrollRouter = useRouter()) {
|
||||
: undefined;
|
||||
|
||||
if (savedPosition === undefined) {
|
||||
const hashTarget = getHashTarget(to.hash);
|
||||
const hashTarget = getHashTarget(scrollElement, to.hash);
|
||||
if (hashTarget) {
|
||||
hashTarget.scrollIntoView({ behavior: 'smooth', block: 'start' });
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user