You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Blazor向导组件前进/后退过渡动画问题求助

问题:Blazor向导前进过渡动画失效,后退动画已正常运行

问题背景

开发Blazor分步安装向导组件,需要可视化展示当前所处步骤。后退操作的过渡动画已实现:通过为div设置双倍尺寸线性渐变背景,修改背景位置达成动画效果——默认背景右侧为灰色,点击“Back”时快速切换为左侧紫色,再通过ontransitionend事件触发缓慢过渡回灰色。但复制镜像逻辑实现前进操作的过渡动画时失败。

已实现的后退动画代码

Blazor组件代码

@for (int i = 0; i <= Steps; i++)
{
   <!-- Current Step -->
   if (i == CurrentStep)
   {
       <div class="step step-current">
           <span>Current @i</span>
       </div>
   }
   <!-- Previous Step -->
   else if (i == CurrentStep - 1)
   {
       <div class="step">
           <span>Previous @i</span>
       </div>
   }
   <!-- Next Step -->
   else if (i == CurrentStep + 1)
   {
       <div class="step step-next-background @StepNextPinkClass() @StepNextAnimateClass()" @ontransitionend="StepNextTransitionEnded">
           <span>Next @i</span>
       </div>
   }
   <!-- Other Steps -->
   else
   {
       <div class="step">
           <span>Other @i</span>
       </div>
   }
}

<div>
   <label>@CurrentStep</label>

   <button type="button" @onclick="e => GoBackwards()">Back</button>

   <button type="button" @onclick="e => GoForward()">Go</button>
</div>


@code{
   int Steps = 20;
   int CurrentStep = 0;

   bool NextPinkBool = false;
   bool NextAnimationBool = false;

   private void GoBackwards()
   {
       StateHasChanged();

       NextPinkBool = true;
       CurrentStep--;

       StateHasChanged();
   }

   private void GoForward()
   {
       CurrentStep++;
   }

   private void StepNextTransitionEnded()
   {
       NextPinkBool = false;
       NextAnimationBool = true;
   }
   private string StepNextPinkClass() => NextPinkBool ? "step-next-fill" : "";

   private string StepNextAnimateClass() => NextAnimationBool ? "step-next-animation" : "";
}

CSS代码

.step {
    width: 150px;
    height: 150px;
    padding: 11px 16px;
    text-align: center;
    float: left;
    background-color: dimgray;
}

.step-current {
    background-color: plum;
}

.step-next-background {
    /* Left (Pink) -> Right (Gray) */
    background: linear-gradient(to right, plum 50%, dimgray 50%);
    background-size: 200% 100%;
    background-position: right top;
}


.step-next-animation {
    transition: background-position 1s ease;
    background-position: right top;
}

.step-next-fill {
    transition: background-position 0.01s ease;
    background-position: left top;
}

自定义EventHandler代码

namespace BlazorModalTestSteps
{
    [EventHandler("ontransitionend", typeof(EventArgs), enableStopPropagation: true, enablePreventDefault: false)]
    [EventHandler("onanimationend", typeof(EventArgs), enableStopPropagation: true, enablePreventDefault: false)]
    [EventHandler("ontransitionstart", typeof(EventArgs), enableStopPropagation: true, enablePreventDefault: false)]
    [EventHandler("ontransitionrun", typeof(EventArgs), enableStopPropagation: true, enablePreventDefault: false)]
    public static class EventHandlers
    {
    }
}

失效的前进动画尝试代码

Blazor组件中对应div代码

<div class="step step-previous-background @StepPreviousPinkClass() @StepPreviousAnimateClass()" @ontransitionend="StepPreviousTransitionEnded">
    <span>Previous @i</span>
</div>

对应C#方法代码

bool PreviousPinkBool = false;
    bool PreviousAnimationBool = false;

    private void StepPreviousTransitionEnded()
    {
        PreviousPinkBool = false;
        PreviousAnimationBool = true;
    }

    private string StepPreviousPinkClass() => PreviousPinkBool ? "step-previous-fill" : "";

    private string StepPreviousAnimateClass() => PreviousAnimationBool ? "step-previous-animation" : "";


    private void GoForward()
    {
        StateHasChanged();

        PreviousPinkBool = true;
        CurrentStep++;

        StateHasChanged();
    }

对应CSS代码

.step-previous-background {
    /* Left (Pink) -> Right (Gray) */
    background: linear-gradient(to left, plum 50%, dimgray 50%);
    background-size: 200% 100%;
    background-position: left top;
}

.step-previous-animation {
    transition: background-position 1s ease;
    background-position: left top;
}

.step-previous-fill {
    transition: background-position 0.01s ease;
    background-position: right top;
}

问题分析与解决方案

前进动画失效的核心原因:

  1. 元素匹配与状态时机不匹配:点击前进时,CurrentStep++后,原当前步骤变为新的CurrentStep-1,但原有逻辑未让该目标元素正确触发过渡状态切换。
  2. CSS渐变与过渡方向错位:前进需要和后退镜像的渐变逻辑,但原有CSS的渐变方向、背景位置切换顺序未对应。

修正后的完整代码

Blazor组件代码

@for (int i = 0; i <= Steps; i++)
{
   <!-- Current Step -->
   if (i == CurrentStep)
   {
       <div class="step step-current">
           <span>Current @i</span>
       </div>
   }
   <!-- Previous Step -->
   else if (i == CurrentStep - 1)
   {
       <div class="step step-previous-background @StepPreviousPinkClass() @StepPreviousAnimateClass()" @ontransitionend="StepPreviousTransitionEnded">
           <span>Previous @i</span>
       </div>
   }
   <!-- Next Step -->
   else if (i == CurrentStep + 1)
   {
       <div class="step step-next-background @StepNextPinkClass() @StepNextAnimateClass()" @ontransitionend="StepNextTransitionEnded">
           <span>Next @i</span>
       </div>
   }
   <!-- Other Steps -->
   else
   {
       <div class="step">
           <span>Other @i</span>
       </div>
   }
}

<div>
   <label>@CurrentStep</label>

   <button type="button" @onclick="e => GoBackwards()" disabled="@(CurrentStep == 0)">Back</button>

   <button type="button" @onclick="e => GoForward()" disabled="@(CurrentStep == Steps)">Go</button>
</div>


@code{
   int Steps = 20;
   int CurrentStep = 0;

   bool NextPinkBool = false;
   bool NextAnimationBool = false;
   bool PreviousPinkBool = false;
   bool PreviousAnimationBool = false;

   private void GoBackwards()
   {
       StateHasChanged();

       NextPinkBool = true;
       CurrentStep--;

       StateHasChanged();
   }

   private void GoForward()
   {
       StateHasChanged();

       PreviousPinkBool = true;
       CurrentStep++;

       StateHasChanged();
   }

   private void StepNextTransitionEnded()
   {
       NextPinkBool = false;
       NextAnimationBool = true;
   }

   private void StepPreviousTransitionEnded()
   {
       PreviousPinkBool = false;
       PreviousAnimationBool = true;
   }

   private string StepNextPinkClass() => NextPinkBool ? "step-next-fill" : "";
   private string StepNextAnimateClass() => NextAnimationBool ? "step-next-animation" : "";
   private string StepPreviousPinkClass() => PreviousPinkBool ? "step-previous-fill" : "";
   private string StepPreviousAnimateClass() => PreviousAnimationBool ? "step-previous-animation" : "";
}

修正后的CSS代码

.step {
    width: 150px;
    height: 150px;
    padding: 11px 16px;
    text-align: center;
    float: left;
    background-color: dimgray;
    margin-right: 8px;
}

.step-current {
    background-color: plum;
}

/* 后退动画:Next元素的渐变(左紫右灰) */
.step-next-background {
    background: linear-gradient(to right, plum 50%, dimgray 50%);
    background-size: 200% 100%;
    background-position: right top;
}

.step-next-fill {
    transition: background-position 0.01s ease;
    background-position: left top;
}

.step-next-animation {
    transition: background-position 1s ease;
    background-position: right top;
}

/* 前进动画:Previous元素的渐变(左灰右紫) */
.step-previous-background {
    background: linear-gradient(to right, dimgray 50%, plum 50%);
    background-size: 200% 100%;
    background-position: left top;
}

.step-previous-fill {
    transition: background-position 0.01s ease;
    background-position: right top;
}

.step-previous-animation {
    transition: background-position 1s ease;
    background-position: left top;
}

修正说明

  1. CSS逻辑对齐:
    • 前进动画的.step-previous-background改为左灰右紫的渐变,默认显示左侧灰色;.step-previous-fill快速切换到右侧紫色,再通过.step-previous-animation过渡回左侧灰色,和后退动画逻辑镜像匹配。
  2. Blazor状态控制:
    • 确保前进时,目标元素(原当前步骤)正确应用过渡类,状态切换顺序和后退保持一致:先触发渲染,再切换状态,最后再次渲染。
  3. 边界处理:添加按钮禁用逻辑,防止越界操作。

修改后,前进和后退的过渡动画均可正常运行,无需额外JavaScript代码。

内容的提问来源于stack exchange,提问作者SideSky

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 23:04:56