Как использовать два стройных перехода на одном переключаемом элементе?
У меня есть поле ввода, которое я хочу скрыть / показать, и делаю это с постепенным переходом между слайдами. У меня есть два примера, которые я придумал, но у обоих есть свои недостатки, и я хотел бы знать, есть ли более элегантное решение.
Мне просто нужен ответ на один из двух вопросов, поскольку оба они решат мою проблему.
Вопрос 1. Есть ли способ вызвать несколько переходов для одной директивы перехода?
Вопрос 2: Как добавить класс, который будет запускать обычный css-переход после того, как оператор if поместит элемент в DOM?
Пример 1
Svelte не допускает двух переходов для одного и того же элемента. Итак, одно из решений - вложить два элемента, как показано ниже. Есть ли способ написать собственный переход, используя как затухание, так и скольжение?
transition:myMultiTransition
?
{#if active === true}
<span transition:fade>
<span transition:slide>
<input type="text" />
</span>
</span>
{/if}
Пример 2
В другом моем решении я просто переключаю активный класс, используя обычные переходы css. Проблема здесь в том, что
<input>
-field никогда не покидает DOM. Это высота 0 пикселей, но оставлять ее там кажется неправильным.
Как успешно показать поле ввода с
{#if active === true}
а потом добавить класс, запускающий эффект перехода? Svelte, кажется, добавляет активный класс, который должен запускать переход до того, как элемент вошел в DOM.
Я пытался использовать
await tick()
,
onMount
,
beforeUpdate
в различных комбинациях без везения.
При добавлении класса с задержкой с помощью setTimeout он работает, но мне не нравится это решение, потому что оно может выйти из строя, если не выбрано точное время, и мне не нужна задержка перед началом перехода.
<span class:{active}>
<input type="text" />
</span>
<style>
.active {
// Normal transition: opacity 1s etc ...
}
</style>
REPL
https://svelte.dev/repl/89cb7d26d9484d0193b4bc6bf59518ef?version=3.38.3
2 ответа
Вы можете создать свою собственную функцию перехода:
<script>
import { cubicOut } from 'svelte/easing';
let visibleDoubleElements = false;
function slidefade(node, params) {
const existingTransform = getComputedStyle(node).transform.replace('none', '');
return {
delay: params.delay || 0,
duration: params.duration || 400,
easing: params.easing || cubicOut,
css: (t, u) => `transform-origin: top left; transform: ${existingTransform} scaleY(${t}); opacity: ${t};`
};
}
</script>
<label>
<input type="checkbox" bind:checked={visibleDoubleElements}>
Svelte transition
</label>
{#if visibleDoubleElements === true}
<input transition:slidefade type="text" placeholder="Double elements" />
{/if}
REPL:https://svelte.dev/repl/da8880947eff4f32b740a8742d9f817e?version=3.38.3
Комбинирование нескольких переходов в одном элементе невозможно в CSS, поэтому я боюсь, что в ближайшем будущем у нас не будет этой функции в Svelte. Возможно, проще всего будет придерживаться первого решения, которое вы уже предоставили: добавление слоя для каждого перехода.
Если вы хотите написать свой собственный переход, вы можете хотя бы попробовать повторно использовать некоторые функции из Svelte: Вот пример для Slide + Fade
function fadeSlide(node, options) {
const slideTrans = slide(node, options)
return {
duration: options.duration,
css: t => `
${slideTrans.css(t)}
opacity: ${t};
`
};
}
https://svelte.dev/repl/f5c42c6dc6774f29ad9350cd2dc2d299?version=3.38.3