我喜欢 Svelte,但我坚持一些基本的东西(尽管只是装饰性的)。下面的代码应该在两个元素之间平滑过渡,但它会“跳跃”——显然是在传入元素到达之前为它腾出空间。
这个问题类似于Rich Harris 几年前指出的问题,但我没有看到解决方案已实施。Svelte 教程站点上的所有示例仅转换一个元素。
这是基本的标记/代码:
{#if div1}
<div
in:fly={{ x: 100, duration: 400, delay: 400 }}
out:fly={{ x: 100, duration: 400 }}>Div 1</div>
{:else}
<div
in:fly={{ x: 100, duration: 400, delay: 400 }}
out:fly={{ x: 100, duration: 400 }}>Div 2</div>
{/if}
<button on:click={()=>{ div1 = !div1}}>Switch</button>
Vue 中的等效工作是:
<transition name="fly" mode="out-in">
<div v-if="div1">Div 1</div>
<div v-else>Div 2</div>
</transition>
这是一个代码沙箱示例。您可以看到按钮向下跳来为新元素腾出空间。我添加了一个等于 400 持续时间的“in”转换延迟(我知道这是默认设置,但为了清楚起见,我想明确设置它)。延迟应该允许第一个元素在转换下一个元素之前转换出来,如第一个链接中所述(Harris 称之为“延迟的骇人使用”)并在此处建议。
我还尝试将被淘汰的元素显式设置为 position: absolute ,这样它就不会占用空间。这是一个(仍然无法正常工作)示例。似乎有点不雅,即使它正在工作。出于某种原因,转换覆盖了设置位置的类:绝对。
任何帮助是极大的赞赏!
更新:我用这段代码得到了想要的效果。我在这里所做的是复制和修改 Svelte 的飞行过渡以获取一个额外的参数——“位置”,它可以设置为“绝对”或“相对”或任何你想要的。对 CSS 进行了一些调整以确保没有奇怪的副作用(将容器设置为 position: relative,并将每个元素的宽度设置为 100% 以确保它们不会改变大小)。这行得通,但我仍然觉得应该有一种不那么劳动密集型的方法,而无需修改 Svelte 的过渡。