svelte
svelte copied to clipboard
Transition not removing extra DOM nodes after completion
Describe the bug
When you have an element with a transition and destroy it, but then recreate it before the transition is done, you can end up with old elements not being removed.
Reproduction
When you type in the input field, the value
is set to what you typed if the value
is empty, otherwise the value
is cleared. Try randomly spamming your keyboard, and a bunch of extra elements should be left there.
Logs
No response
System Info
System:
OS: macOS 10.15.7
CPU: (8) x64 Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz
Memory: 1.35 GB / 32.00 GB
Shell: 3.2.2 - /usr/local/bin/fish
Binaries:
Node: 16.13.1 - /var/folders/gs/3qcm1mc918s08sxvkj6zj2rr0000gp/T/fnm_multishells/87890_1641758181492/bin/node
Yarn: 1.22.17 - /var/folders/gs/3qcm1mc918s08sxvkj6zj2rr0000gp/T/fnm_multishells/87890_1641758181492/bin/yarn
npm: 8.1.2 - /var/folders/gs/3qcm1mc918s08sxvkj6zj2rr0000gp/T/fnm_multishells/87890_1641758181492/bin/npm
Browsers:
Brave Browser: 96.1.32.106
Chrome: 96.0.4664.110
Firefox: 95.0.2
Safari: 15.2
npmPackages:
svelte: ^3.45.0 => 3.45.0
Severity
annoyance
This issue might be what's causing https://github.com/sveltejs/svelte/issues/1591
A possible cause of this issue is an active transition belonging to a child component, in this case applying the local
modifier may resolve the issue.
https://svelte.dev/tutorial/local-transitions https://svelte.dev/docs#template-syntax-element-directives-transition-fn
Bumping this with another repro for what looks like the same underlying issue:
When having an If Block with an Each block inside it that creates a component, like
{#if active.length > 0}
<div transition:fly={{ x: -10, duration: 1000 }}>
{#each active as mod}
<Mod mod={mod}/>
{/each}
</div>
{/if}
Changing the active
array to have some elements like [1,2,3,4,5,6]
; then changing it to be empty []
; and then while the remove transition from the if block is playing, changing it to have elements again but be shorter than the original array ["aaa","bbb"]
, some elements generated from the first array will remain visible, as if the array had the contents ["aaa","bbb",3,4,5,6]
Repro: https://svelte.dev/repl/b11e64abca0141689162c85954a06920?version=4.2.10
When clicking the button slowly, it will switch between no elements; elements for [1,2,3,4,5,6]
; elements for ["aaa","bbb"]
.
When clicking the button quickly (quicker than the 1s animation time), it will switch between no elements; elements for [1,2,3,4,5,6]
; elements for ["aaa","bbb",3,4,5,6]
(Incorrect behavior!).
The same code seems to work correctly in the Svelte5 playground.
The behavior also does not occour if the content of the each block is a normal Element instead of a Svelte component.
The problem is not solved by using a keyed each block (this just leads to the new elements not overwriting the old ones, instead producing HTML for ["aaa","bbb",1,2,3,4,5,6]
, which is still incorrect).
Help thread on the Svelte Discord about this can be found here
that's definitely a bug on the diffing for the transition where the elements don't experience a keyed "destroy"