SvelteKit图片轮播{#each}渲染时fade过渡动画不生效问题
问题根源
过渡不生效核心是2个问题:
{#each}循环没有指定唯一key:Svelte默认按列表位置对比DOM变化,你每次切片后永远只返回1个img元素,Svelte会判定为「同一个DOM节点仅修改了src属性」,不会触发元素创建/销毁对应的过渡动画,直接替换图片资源导致闪烁。- 切片逻辑的初始值和切换逻辑不匹配:初始
selected=1、prevSelected=0时slice(0,1)仅返回索引为0的图片,切换时新旧图片没有同时存在的过渡窗口,旧图直接被移除出新数组,新图直接替换位置。
另外你引入了slide过渡但没有使用,属于冗余代码不影响功能。
修复方案
- 给
{#each}循环添加唯一key,用图片自带的Index字段作为唯一标识,让Svelte能正确追踪每个图片元素的增删 - 单图切换的淡入淡出效果用
{#key}块实现更简洁,绑定当前选中的图片索引后,每次索引变化会自动销毁旧元素、创建新元素,触发过渡 - 修正索引判断逻辑,避免数组越界
修复后可运行代码
<script> import { fade } from 'svelte/transition'; let images = [ { Index: 0, src: 'src/images/img2.jpeg', alt: 'znaki ewakuacyjne', class: 'show' }, { Index: 1, src: 'src/images/img3.jpeg', alt: 'buty', class: '' }, { Index: 2, src: 'src/images/img4.jpeg', alt: 'znaki informacyjne', class: '' } ]; // 初始默认显示第一张图,索引从0开始 let selected = 0; function handleClick() { if (selected >= images.length - 1) { return; } selected += 1; } function handleBack() { if (selected <= 0) { return; } selected -= 1; } </script> <h3 class="text-center font-semibold text-xl m-3">Galeria</h3> <div class="image-gallery flex flex-col justify-center items-center"> <!-- 用key块绑定选中索引,变化时自动触发过渡 --> {#key selected} <img transition:fade src={images[selected].src} alt={images[selected].alt} class="h-80 w-50 rounded-lg" /> {/key} <div class="flex flex-row gap-12"> <button on:click={handleBack} type="button" class="text-white bg-red-700 hover:bg-red-800 focus:outline-none focus:ring-4 focus:ring-red-300 font-medium rounded-full text-sm px-5 py-2.5 text-center mr-2 mb-2 dark:bg-red-600 dark:hover:bg-red-700 dark:focus:ring-red-900 m-3" >⬅️</button > <button on:click={handleClick} type="button" class="text-white bg-blue-700 hover:bg-blue-800 focus:outline-none focus:ring-4 focus:ring-blue-300 font-medium rounded-full text-sm px-5 py-2.5 text-center mr-2 mb-2 dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800 m-3" >➡️</button > </div> </div> <style lang="scss"> </style>
如果你要保留each加切片的实现方式,只需要给each加唯一key即可,写法为:
{#if shown} {#each images.slice(prevSelected, selected) as img (img.Index)} <img transition:fade src={img.src} alt={img.alt} class="h-80 w-50 rounded-lg" /> {/each} {/if}
注意:这种切片写法下,切换时旧图和新图的切片范围没有重叠,旧图会执行淡出、新图同时执行淡入,需要给图片容器加固定高度避免布局抖动。
Tailwind CSS本身不会干扰Svelte过渡效果,不需要额外调整配置。
内容的提问来源于stack exchange,提问作者Krystioz
相关产品推荐
相关产品推荐

