sveltejs / kit

web development, streamlined
https://kit.svelte.dev
MIT License
18.43k stars 1.89k forks source link

Incorrect scrolling behavior when opening links with a hash #2023

Closed lovasoa closed 2 years ago

lovasoa commented 3 years ago

Describe the bug

Hash links do not always scroll to the right position in the target page.

Reproduction

Here is a repo that reproduces the bug: https://github.com/lovasoa/sanipasse

From the root of the repo, run npm run dev, then on http://localhost:3000 click the first link ("strictement privΓ©e"). You'll end up at the bottom of the page on http://localhost:3000/apropos#donnees instead of scrolling to the right heading ("πŸ”’ Protection des donnΓ©es personnelles"). You can see that svelte's scrolling behavior is incorrect by comparing the same link when opened in a new tab.

Logs

No response

System Info

System:
    OS: Linux 5.13 Fedora 34 (Workstation Edition) 34 (Workstation Edition)
    CPU: (8) x64 Intel(R) Core(TM) i7-10510U CPU @ 1.80GHz
    Memory: 3.66 GB / 15.28 GB
    Container: Yes
    Shell: 5.1.0 - /bin/bash
  Binaries:
    Node: 16.4.0 - /usr/bin/node
    Yarn: 1.22.10 - /usr/bin/yarn
    npm: 7.18.1 - /usr/bin/npm
  Browsers:
    Firefox: 90.0.2
  npmPackages:
    @sveltejs/adapter-node: next => 1.0.0-next.35 
    @sveltejs/adapter-static: next => 1.0.0-next.13 
    @sveltejs/kit: next => 1.0.0-next.137 
    svelte: ^3.38.3 => 3.41.0

Severity

serious, but I can work around it

Additional Information

By adding a breakpoint on

            deep_linked.scrollIntoView();

in svelte's router.js you see where the problem is. The call to scrollIntoView happens before the contents from the old page are removed from the DOM.

benmccann commented 3 years ago

I was not able to run your example. After doing npm install and then npm run dev, I get:

performance is not defined
ReferenceError: performance is not defined
lovasoa commented 3 years ago

The code requires node >=16. Are you on the latest version of node ?

lovasoa commented 3 years ago

There is also a Dockerfile provided if you don't want to install anything locally.

benmccann commented 3 years ago

Ok, I switched to Node 16 and it runs now, but I can't reproduce it. Could it possible be a race condition? Can you explain more about what you believe the cause of the issue is?

lovasoa commented 3 years ago

To help with reproduction, here is my npm ls :

sanipasse@1.0 /workspaces/sanipasse
β”œβ”€β”€ @ctrl/ts-base32@1.2.6
β”œβ”€β”€ @peculiar/x509@1.3.2
β”œβ”€β”€ @sveltejs/adapter-node@1.0.0-next.33
β”œβ”€β”€ @sveltejs/adapter-static@1.0.0-next.13
β”œβ”€β”€ @sveltejs/kit@1.0.0-next.127
β”œβ”€β”€ @types/pako@1.0.2
β”œβ”€β”€ @typescript-eslint/eslint-plugin@4.28.3
β”œβ”€β”€ @typescript-eslint/parser@4.28.3
β”œβ”€β”€ @zxing/browser@0.0.9
β”œβ”€β”€ @zxing/library@0.18.6
β”œβ”€β”€ ajv@8.6.1
β”œβ”€β”€ base45-ts@1.0.3
β”œβ”€β”€ base64-js@1.5.1
β”œβ”€β”€ bignumber.js@9.0.1
β”œβ”€β”€ bootstrap-icons@1.5.0
β”œβ”€β”€ bootstrap@5.0.2
β”œβ”€β”€ buffer@6.0.3
β”œβ”€β”€ cbor-web@7.0.6
β”œβ”€β”€ cbor@7.0.6
β”œβ”€β”€ cosette@0.6.1
β”œβ”€β”€ eslint-config-prettier@8.3.0
β”œβ”€β”€ eslint-plugin-svelte3@3.2.0
β”œβ”€β”€ eslint@7.30.0
β”œβ”€β”€ isomorphic-webcrypto@2.3.8
β”œβ”€β”€ localforage@1.9.0
β”œβ”€β”€ node-fetch@2.6.1
β”œβ”€β”€ pako@2.0.3
β”œβ”€β”€ pdfjs-dist@2.8.335
β”œβ”€β”€ prettier-plugin-svelte@2.3.1
β”œβ”€β”€ prettier@2.2.1
β”œβ”€β”€ sequelize@6.6.5
β”œβ”€β”€ sqlite3@5.0.2
β”œβ”€β”€ svelte-check@1.6.0
β”œβ”€β”€ svelte-preprocess@4.7.4
β”œβ”€β”€ svelte@3.38.3
β”œβ”€β”€ sveltestrap@5.4.0
β”œβ”€β”€ tslib@2.3.0
β”œβ”€β”€ typescript@4.3.5
β”œβ”€β”€ workbox-precaching@6.1.5
└── workbox-recipes@6.1.5

When placing a breakpoint on deep_linked.scrollIntoView(); in router.js. I can see that it is being called while the contents of the old page (the one on which the |<a> tag is) is still in the dom and and displayed on screen when it is called.

lovasoa commented 3 years ago

image

lovasoa commented 3 years ago

@benmccann : my website https://sanipasse.fr/ uses multiple internal hash links and suffers from this bug. What are the next steps towards fixing it ? Do you need any further information from me ?

dummdidumm commented 2 years ago

No longer reproducible. The code in question now has await tick() before it which should give enough time to rerender the components so scrolling works.