天津储鑫盛钢材现货供应商 发表于 2023-1-8 01:05:51

Blazor实现菜单动画

想到动画,你可能会去安装Blazor的动画组件BlazorAnimate,然后使用它。本人初学,暂时我也不知道原理,先不用组件,自己实现吧。虽然项目中我用了AntDesignBlazor,但是我忘了使用它的菜单组件,我用的菜单组件还是VS2022自动生成的,后来我把这个菜单改造了一下,支持多级菜单,加了展示收缩箭头,那就在这基础上做吧。
1. 引用jQuery

这里使用jquery的animate方法实现动画
在wwwroot/js目录放一个jquery-1.9.1.js文件,然后在html(或_Layout.cshtml文件)中引入该js
https://img2023.cnblogs.com/blog/174862/202301/174862-20230107155259265-653685869.png
2. 为左侧菜单组件NavMenu.razor添加一个js文件:NavMenu.razor.js

https://img2023.cnblogs.com/blog/174862/202301/174862-20230107161203858-942550004.png
内容如下:
export function animate(index) { //index是菜单编码 2位数是一级菜单,4位数是二级菜单,以此类推
    let time = 200;
    let content = $(".content" + index);
    let h = content.height() + "px";
    content.css("overflow", "hidden");

    if (index <= 99 || content.hasClass("collapse")) { //index<=99表示一级菜单,一级菜单只有展开动画,没有收缩动画;content.hasClass("collapse")表示当前是收缩状态。
      content.css("height", "0");
      //展开动画
      content.animate({
            height: h
      }, time, "linear", () => {
            content.css("height", "auto");
      });
    } else { //不是一级菜单并且当前是展开状态,将执行收缩动画
      content.css("height", "auto");
      //收缩动画
      content.animate({
            height: 0
      }, time, "linear", () => {
            setTimeout(function () { //延迟执行,否则会导致闪烁
                content.css("height", "auto");
            }, 100);
      });
      return ; //收缩时,需要等待收缩动画展示完成,再隐藏菜单容器div
    }
    return ;
}3. 在Blazor组件NavMenu.razor文件中引入该js

@inject IJSRuntime _js;

@code {
    IJSObjectReference _module;

    protected override async void OnAfterRender(bool firstRender)
    {
      if (firstRender)
      {
            _module = await _js.InvokeAsync<IJSObjectReference>("import", "./Shared/NavMenu.razor.js");
      }
    }
}4. 调用js方法实现菜单动画

@code{
    ...省略此处的代码
   
    private async Task ToggleMenuClick(int index)
    {
      object[] args = new object[] { index };
      object[] objs = await _module.InvokeAsync<object[]>("animate", args);
      int time = ((JsonElement)objs).GetInt32();
      if (time > 0) { await Task.Delay(time); } //time大于0,表示需要等待收缩动画展示完成,再隐藏菜单容器div

      if (index > 99)
      {
            if (_dict.ContainsKey(index))
            {
                _dict = !_dict; //记录非一级菜单的展开状态
            }
            else
            {
                _dict = false; //记录非一级菜单的展开状态
            }
      }
      else
      {
            _index = index; //_index是当前展示的菜单编码
      }
    }

    ...省略此处的代码
}效果图

https://img2023.cnblogs.com/blog/174862/202301/174862-20230107160725167-1124844555.gif
NavMenu.razor页面完整代码如下

@using System.Text.Json;
@inject IJSRuntime _js;


await ToggleMenuClick(01))">
   
      <atarget="_blank" href="https://www.cnblogs.com/javascript:void(0);">任务管理</a>
      <button title="Navigation menu" >
            
      </button>
      
   




    <nav >
      
            <NavLinkhref="kpTask/taskList">
               任务列表
            </NavLink>
      
      
            <NavLinkhref="kpTask/taskRunList">
               任务执行记录
            </NavLink>

            
            <NavLinktarget="_blank" href="https://www.cnblogs.com/javascript:void(0);" @onclick="@(()=> ToggleMenuClick(0101))" >
               测试二级菜单组
               
            </NavLink>

            
            
                <nav >
                  
                        <NavLinkhref="counter">
                           测试二级菜单
                        </NavLink>

                        
                        <NavLinktarget="_blank" href="https://www.cnblogs.com/javascript:void(0);" @onclick="@(()=> ToggleMenuClick(010101))" >
                           测试三级菜单组
                           
                        </NavLink>

                        
                        
                            <nav >
                              
                                    <NavLinkhref="counter">
                                       测试三级菜单
                                    </NavLink>
                              
                            </nav>
                        
                  
                  
                        <NavLinkhref="counter">
                           测试二级菜单2
                        </NavLink>
                  
                </nav>
            
      
    </nav>



await ToggleMenuClick(02))">
   
      <atarget="_blank" href="https://www.cnblogs.com/javascript:void(0);">任务管理</a>
      <button title="Navigation menu" >
            
      </button>
      
   




    <nav >
      
            <NavLinkhref="kpTask/taskList">
               任务列表
            </NavLink>
      
      
            <NavLinkhref="kpTask/taskRunList">
               任务执行记录
            </NavLink>

            
            <NavLinktarget="_blank" href="https://www.cnblogs.com/javascript:void(0);" @onclick="@(()=> ToggleMenuClick(0201))" >
               测试二级菜单组
               
            </NavLink>

            
            
                <nav >
                  
                        <NavLinkhref="counter">
                           测试二级菜单
                        </NavLink>
                  
                </nav>
            
      
    </nav>



await ToggleMenuClick(03))">
   
      <atarget="_blank" href="https://www.cnblogs.com/javascript:void(0);">任务管理</a>
      <button title="Navigation menu" >
            
      </button>
      
   




    <nav >
      
            <NavLinkhref="kpTask/taskList">
               任务列表
            </NavLink>
      
      
            <NavLinkhref="kpTask/taskRunList">
               任务执行记录
            </NavLink>

            
            <NavLinktarget="_blank" href="https://www.cnblogs.com/javascript:void(0);" @onclick="@(()=> ToggleMenuClick(0301))" >
               测试二级菜单组
               
            </NavLink>

            
            
                <nav >
                  
                        <NavLinkhref="counter">
                           测试二级菜单
                        </NavLink>
                  
                </nav>
            
      
    </nav>


@code {
    int _index = 01;
    Dictionary<int, bool> _dict = new Dictionary<int, bool>();
    IJSObjectReference _module;

    protected override async void OnAfterRender(bool firstRender)
    {
      if (firstRender)
      {
            _module = await _js.InvokeAsync<IJSObjectReference>("import", "./Shared/NavMenu.razor.js");
      }
    }

    private async Task ToggleMenuClick(int index)
    {
      object[] args = new object[] { index };
      object[] objs = await _module.InvokeAsync<object[]>("animate", args);
      int time = ((JsonElement)objs).GetInt32();
      if (time > 0) { await Task.Delay(time); }

      if (index > 99)
      {
            if (_dict.ContainsKey(index))
            {
                _dict = !_dict;
            }
            else
            {
                _dict = false;
            }
      }
      else
      {
            _index = index;
      }
    }

    private string MenuGroupContentClass(int index)
    {
      if (index > 99)
      {
            if (!_dict.ContainsKey(index) || _dict)
            {
                return $"collapse content{index}";
            }
            else
            {
                return $"content{index}";
            }
      }
      else
      {
            if (index == _index)
            {
                return $"content{index}";
            }
            else
            {
                return $"collapse content{index}";
            }
      }
    }

    private string ArrowClass(int index)
    {
      if (index > 99)
      {
            if (!_dict.ContainsKey(index) || _dict)
            {
                return "arrow-collapse arrow-float";
            }
            else
            {
                return "arrow arrow-float";
            }
      }
      else
      {
            if (index == _index)
            {
                return "arrow";
            }
            else
            {
                return "arrow-collapse";
            }
      }
    }

}
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
页: [1]
查看完整版本: Blazor实现菜单动画