最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Animate list items (stagger) on the initial render of list - Stack Overflow

programmeradmin1浏览0评论

I am trying to build a navigation which staggers the appearance of the contained list items when the menu/navigation is shown.

I have a burger symbol, and when clicked it renders the navigation (fullscreen). I would now like to have an animation, where the different list items (actual links) appear with some delay to each other, the top one being the first and the bottom one the last.

I thought I could do this with vue's <transition-group> and list transitions, but all the examples are about adding and removing list items, whereas I have all of them from the beginning.

I then read about this: Vue.js: Staggering List Transitions And I thought that might be it. Unfortunately I could not get it to work either.

Do you have any hints how I could do that?

So far, I render the navigation with v-if:

<transition name="u-anim-fade" mode="in-out">
  <Navigation v-if="navMenuOpen" />
</transition>

Within the Navigation ponent:

<nav>
    <ul class="Navigation__list">
      <li
        v-for="(item, key) in menu.items"
        class="Navigation__item"
        :key="`nav-item-${key}`">
        <nuxt-link>
          <span v-html="item.title" />
        </nuxt-link>
    </ul>
</nav>

(I left out some stuff simplify the code here)

When I add the enter/leave/onEnter functions which are suggested here: Vue.js: Staggering List Transitions

v-bind:css="false"
v-on:before-enter="beforeEnter"
v-on:enter="enter"
v-on:leave="leave"

Like so:

<nav>
    <transition-group
      name="staggered-fade"
      tag="ul"
      class="Navigation__list"
      v-bind:css="false"
      v-on:before-enter="beforeEnter"
      v-on:enter="enter"
      v-on:leave="leave"
    >
      <li
        v-for="(item, key) in menu.items"
        class="Navigation__item"
        :key="`nav-item-${key}`">
        <nuxt-link>
          <span v-html="item.title" />
        </nuxt-link>
    </transition-group>
</nav>

The methods (which I add to the methods of course) would not even be executed when I render the Navigation ponent. Probably because the items are not added or removed.

I am trying to build a navigation which staggers the appearance of the contained list items when the menu/navigation is shown.

I have a burger symbol, and when clicked it renders the navigation (fullscreen). I would now like to have an animation, where the different list items (actual links) appear with some delay to each other, the top one being the first and the bottom one the last.

I thought I could do this with vue's <transition-group> and list transitions, but all the examples are about adding and removing list items, whereas I have all of them from the beginning.

I then read about this: Vue.js: Staggering List Transitions And I thought that might be it. Unfortunately I could not get it to work either.

Do you have any hints how I could do that?

So far, I render the navigation with v-if:

<transition name="u-anim-fade" mode="in-out">
  <Navigation v-if="navMenuOpen" />
</transition>

Within the Navigation ponent:

<nav>
    <ul class="Navigation__list">
      <li
        v-for="(item, key) in menu.items"
        class="Navigation__item"
        :key="`nav-item-${key}`">
        <nuxt-link>
          <span v-html="item.title" />
        </nuxt-link>
    </ul>
</nav>

(I left out some stuff simplify the code here)

When I add the enter/leave/onEnter functions which are suggested here: Vue.js: Staggering List Transitions

v-bind:css="false"
v-on:before-enter="beforeEnter"
v-on:enter="enter"
v-on:leave="leave"

Like so:

<nav>
    <transition-group
      name="staggered-fade"
      tag="ul"
      class="Navigation__list"
      v-bind:css="false"
      v-on:before-enter="beforeEnter"
      v-on:enter="enter"
      v-on:leave="leave"
    >
      <li
        v-for="(item, key) in menu.items"
        class="Navigation__item"
        :key="`nav-item-${key}`">
        <nuxt-link>
          <span v-html="item.title" />
        </nuxt-link>
    </transition-group>
</nav>

The methods (which I add to the methods of course) would not even be executed when I render the Navigation ponent. Probably because the items are not added or removed.

Share Improve this question edited Jul 14, 2022 at 1:19 tony19 139k23 gold badges277 silver badges347 bronze badges asked Apr 7, 2018 at 2:22 MercMerc 4,5808 gold badges58 silver badges87 bronze badges 3
  • 1 Maybe you're missing the appear option on the transition-group? – Emile Bergeron Commented Apr 7, 2018 at 2:28
  • Also, the closing </li> looks missing. – Emile Bergeron Commented Apr 7, 2018 at 2:37
  • 1 the li got lost when I simplified the code :) – Merc Commented Apr 7, 2018 at 4:02
Add a ment  | 

2 Answers 2

Reset to default 5

Probably because the items are not added or removed.

You're right, and what you need is this:

Transitions on Initial Render

If you also want to apply a transition on the initial render of a node, you can add the appear attribute:

<transition appear>
  <!-- ... -->
</transition>

I just tried it and if not present, the listener functions aren't called on the initial render.

Note that it works as well with <transition-group> ponents.

For vue 3 user, with GSAP

<template>
  <div>
    <transition-group 
      appear
      tag="ul"
      @before-enter="beforeEnter"
      @enter="enter"
    >
      <li v-for="(item, index) in items" :key="icon.name" :data-index="index">
        <div>{{ item.text }}</div>
      </li>
    </transition-group>
  </div>
</template>

<script>
import { ref } from 'vue'
import { gsap } from 'gsap'
export default {
  setup() {
    const items = ref([
      { text: 'by email' },
      { text: 'by phone' },
    ])
    const beforeEnter = (el) => {
      el.style.opacity = 0
      el.style.transform = 'translateY(100px)'
    }
    const enter = (el, done) => {
      gsap.to(el, {
        opacity: 1,
        y: 0,
        duration: 0.8,
        onComplete: done,
        delay: el.dataset.index * 0.2
      })
    }
    return { items, beforeEnter, enter }
  }
}
</script>

More info here

发布评论

评论列表(0)

  1. 暂无评论