Skip to content

Commit dbf9d12

Browse files
fix: smooth scroll to deep link (#14569)
* fix: smooth scroll to deep link * remove log Removed console log for scroll position. * Update packages/kit/src/runtime/client/client.js Co-authored-by: Simon H <[email protected]> --------- Co-authored-by: Simon H <[email protected]>
1 parent b5000df commit dbf9d12

File tree

2 files changed

+20
-5
lines changed

2 files changed

+20
-5
lines changed

.changeset/stale-things-mix.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@sveltejs/kit': patch
3+
---
4+
5+
fix: smoothscroll to deep link

packages/kit/src/runtime/client/client.js

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1700,7 +1700,7 @@ async function navigate({
17001700
await tick();
17011701

17021702
// we reset scroll before dealing with focus, to avoid a flash of unscrolled content
1703-
const scroll = popped ? popped.scroll : noscroll ? scroll_state() : null;
1703+
let scroll = popped ? popped.scroll : noscroll ? scroll_state() : null;
17041704

17051705
if (autoscroll) {
17061706
const deep_linked = url.hash && document.getElementById(get_id(url));
@@ -1711,6 +1711,15 @@ async function navigate({
17111711
// because it natively supports the `scroll-margin` and `scroll-behavior`
17121712
// CSS properties.
17131713
deep_linked.scrollIntoView();
1714+
1715+
// Get target position at this point because with smooth scrolling the scroll position
1716+
// retrieved from current x/y above might be wrong (since we might not have arrived at the destination yet)
1717+
const { top, left } = deep_linked.getBoundingClientRect();
1718+
1719+
scroll = {
1720+
x: pageXOffset + left,
1721+
y: pageYOffset + top
1722+
};
17141723
} else {
17151724
scrollTo(0, 0);
17161725
}
@@ -1724,7 +1733,7 @@ async function navigate({
17241733
document.activeElement !== document.body;
17251734

17261735
if (!keepfocus && !changed_focus) {
1727-
reset_focus(url);
1736+
reset_focus(url, scroll);
17281737
}
17291738

17301739
autoscroll = true;
@@ -2464,7 +2473,7 @@ function _start_router() {
24642473
// /#top and click on a link that goes to /#top. In those cases just go to
24652474
// the top of the page, and avoid a history change.
24662475
if (hash === '' || (hash === 'top' && a.ownerDocument.getElementById('top') === null)) {
2467-
window.scrollTo({ top: 0 });
2476+
scrollTo({ top: 0 });
24682477
} else {
24692478
const element = a.ownerDocument.getElementById(decodeURIComponent(hash));
24702479
if (element) {
@@ -2923,8 +2932,9 @@ let resetting_focus = false;
29232932

29242933
/**
29252934
* @param {URL} url
2935+
* @param {{ x: number, y: number } | null} scroll
29262936
*/
2927-
function reset_focus(url) {
2937+
function reset_focus(url, scroll = null) {
29282938
const autofocus = document.querySelector('[autofocus]');
29292939
if (autofocus) {
29302940
// @ts-ignore
@@ -2936,7 +2946,7 @@ function reset_focus(url) {
29362946
// starting point to the fragment identifier.
29372947
const id = get_id(url);
29382948
if (id && document.getElementById(id)) {
2939-
const { x, y } = scroll_state();
2949+
const { x, y } = scroll ?? scroll_state();
29402950

29412951
// `element.focus()` doesn't work on Safari and Firefox Ubuntu so we need
29422952
// to use this hack with `location.replace()` instead.

0 commit comments

Comments
 (0)