【问题标题】:Transition group animation changes behaviour when adding 3rd element过渡组动画在添加第三个元素时改变行为
【发布时间】:2019-03-15 22:17:51
【问题描述】:

上下文:我在页面顶部有一个div,用于显示/隐藏按钮。 div 位于按钮下方和内容上方。我使用了transition-group,以便其余内容在显示/隐藏时在div 上向上/向下滑动。内容有一个margin-top,因此它限制了上面显示/隐藏的div

需要:我想在div 顶部留出一个边距,这样当它显示时,它会在自身和按钮之间保留空间。 https://imgur.com/UG5iakC

问题:我尝试了两种方法:

1) 为隐藏的div 放置一个margin-top。 因为我在隐藏div 时有position:absolute,以便内容超过div,所以div 调整为内容的大小,因此边距自动变小;所以在隐藏它的时候,边距在隐藏之前变小了,而且很丑。 GIFhttps://gph.is/2QInDfj

2) div 上方的transition-group 内添加一个hr 如果没有hr,则幻灯片在div 上按预期工作。但是当我添加hr 并单击以隐藏div 时,幻灯片会按预期发生,但divhr 会立即消失,而不是显示出来,内容滑过它并覆盖它。 GIFhttps://gph.is/2yd4JGt

所需的视觉效果,顶部没有边距/小时: https://gph.is/2OPZyFV

HTML

<transition-group name="slide">
    <hr class="m-0" v-if="isVisible" key='h'>
    <div class="d-flex" v-if="isVisible" id="filters" key='x'>
        <div class="pl-5">
            <p class="filterTitles">Day</p>
            <app-day-filter v-for="day in weekDay" 
                :key="day.index" 
                :day="day">
            </app-day-filter>
        </div>
        <div class="pl-5">
            <p class="filterTitles">Time of day</p>
            <app-tod-filter v-for="todf in tod" 
                :key="tod.index" 
                :todf="todf">
            </app-tod-filter>
        </div>
    </div>
    <app-event v-for='(eveniment, index) in filterEvent' 
        :key='index' 
        :eveniment='eveniment' 
        :index='index'></app-event>
</transition-group>

CSS

.slide-enter {
    opacity:0;
}
.slide-enter-active {
    transition: all 1s ease-out;
}
.slide-leave-active{
    transition: all 1s ease-out;
    opacity: 0;
    position: absolute;
}
.slide-move {
    transition: transform 1s;
}
#filters {
/* border-top: 1px solid lightgrey; */
}

建议?

谢谢

【问题讨论】:

    标签: javascript html css vue.js transition


    【解决方案1】:

    这主要是一个 CSS 问题。

    如果hr 元素被引入到transition-group 内的布局中,并且transition CSS 属性与all 相关,position 正在设置在leave-active 状态期间到absolute(这将导致元素从其先前的布局流中的相对位置“消失”),然后将同时转换大量元素和属性,从而导致不良效果。

    但是,鉴于问题寻求解决方案没有marginhr 位于transition-group 之上,并假设按钮具有事件处理程序,如下所示:

    <button class="filter-button" v-on:click="toggleSlider">Filters</button>
    

    函数toggleSlider 将切换动画过渡所依赖的isVisible 属性:

    methods: {
      toggleSlider() {
        this.isVisible = !this.isVisible;
      }
    }
    

    而使用 CSS,而不是转换 all,只需转换将实现追捧效果的属性,即 opacity,并使用此答案,max-height。通过完全去除绝对定位,并使用相对位置加上 z-indexing 和下面的 CSS,达到了预期的效果。

    /* put margin spacing on the bottom of the button */
    .filter-button {
      margin-bottom: 25px;
    }
    
    /* add relative positioning to enforce z-indexing */
    .filter-group {
      position: relative;
      z-index: 1;
    }
    
    /* add relative positioning to enforce z-indexing */
    .filter-content {
      position: relative;
      z-index: 2;
    }
    
    /* hidden states */
    .slide-enter,
    .slide-leave-to {
      opacity: 0;
      max-height: 0px;
    }
    
    /* shown states - max-height can be adjusted as desired */
    .slide-enter-to,
    .slide-leave {
      opacity: 1;
      max-height: 300px;
    }
    
    /* while animating during animation entry phase */
    .slide-enter-active {
      transition: opacity 0.75s ease-in, max-height 0.5s ease-out;
    }
    
    /* while animating during the animation departure phase */
    .slide-leave-active {
      transition: opacity 0.75s ease-out, max-height 0.5s ease-out;
    }
    
    /* add padding to bottom of filters section */
    .pl-5 {
      padding-bottom: 25px;
    }
    

    通过在按钮底部和过滤器部分添加边距,可以保留部分之间的间距。

    我创建了一个CodeSandbox 来说明这个解决方案。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-08-19
      • 2017-03-28
      • 2012-03-17
      • 2022-11-30
      • 2011-06-22
      • 1970-01-01
      • 2013-05-08
      • 2012-05-16
      相关资源
      最近更新 更多