好长时间没继续写这个系列博客了, 不知道大家还记得我吗? 话不多说,直接开撸.
配套源码
demo https://blazor.app1.es/b19LongPressButton
####1. 新建 net8 blazor 工程 b19LongPressButton
至于用什么模式大家各取所需, 我创建的是ssr单工程, 如果大家不小心建立错了按页面渲染模式,可以在 App.razor 里面改一下, 加入 @rendermode=“RenderMode.InteractiveServer” 这句话, 默认使用ssr模式渲染.
<Routes @rendermode="RenderMode.InteractiveServer" />
####2. Components\Pages 下新建组件 LongPressButton.razor
@inherits ComponentBase<div @onclick="onClick" @oncontextmenu="onContextMenu" @ontouchstart="OnTouchStart" @ontouchend="OnTouchEnd">@ChildContent
</div>@code {[Inject]private IJSRuntime? JS { get; set; }[Parameter]public RenderFragment? ChildContent { get; set; }/// <summary>/// 获得/设置 启用长按/// </summary>[Parameter]public bool LongPress { get; set; } = true;/// <summary>/// 获得/设置 ContextMenu 菜单项回调委托/// </summary>[Parameter]public Func<MouseEventArgs, Task>? OnContextMenu { get; set; }/// <summary>/// 获得/设置 长按回调委托, 如果启用长按并且不是触摸设备,则回落到 Click 点击时触发/// </summary>[Parameter]public Func<MouseEventArgs, Task>? OnLongPress { get; set; }/// <summary>/// 获得/设置 Click 回调委托/// </summary>[Parameter]public Func<MouseEventArgs, Task>? OnClick { get; set; }/// <summary>/// 获得/设置 长按延时/// </summary>[Parameter]public int OnTouchTime { get; set; } = 500;/// <summary>/// ContextMenu 菜单项点击时触发/// </summary>/// <returns></returns>Task onContextMenu(MouseEventArgs args){if (OnContextMenu != null){return OnContextMenu.Invoke(args);}else{return Task.CompletedTask;}}/// <summary>/// 点击时触发/// </summary>/// <returns></returns>Task onClick(MouseEventArgs args){if (OnClick != null){return OnClick.Invoke(args);}else if (OnLongPress != null && !IsTouchDevice){return OnLongPress.Invoke(args);}else{return Task.CompletedTask;}}/// <summary>/// 是否触摸设备/// </summary>private bool IsTouchDevice { get; set; }/// <summary>/// 是否触摸/// </summary>private bool TouchStart { get; set; }/// <summary>/// 触摸定时器工作指示/// </summary>private bool IsBusy { get; set; }protected override async Task OnAfterRenderAsync(bool firstRender){if (firstRender){IsTouchDevice = await JS!.InvokeAsync<bool>("eval", $"'ontouchstart' in document.documentElement");}}private async Task OnTouchStart(TouchEventArgs e){if (!IsBusy){IsBusy = true;TouchStart = true;// 延时保持 TouchStart 状态await Task.Delay(OnTouchTime);if (TouchStart){var args = new MouseEventArgs(){ClientX = e.Touches[0].ClientX,ClientY = e.Touches[0].ClientY,ScreenX = e.Touches[0].ScreenX,ScreenY = e.Touches[0].ScreenY,Type = "LongPress"};// 弹出关联菜单if (OnContextMenu != null)await OnContextMenu(args);if (OnLongPress != null)await OnLongPress(args);//延时防止重复激活菜单功能await Task.Delay(OnTouchTime);}IsBusy = false;}}private void OnTouchEnd(){TouchStart = false;}}
####3. 回到首页 Home.razor 添加组件测试
@page "/"<PageTitle>Home</PageTitle><LongPressButton OnLongPress="TaskOnLongPress" > <div style="width:200px;height:100px;background-color:gold;"><p>LongPressButton</p></div>
</LongPressButton><p>@message</p>@code {string message = "No long press";private Task TaskOnLongPress(MouseEventArgs e){message = e.Type;StateHasChanged();return Task.CompletedTask;}
}
####4. 测试
运行程序
普通浏览器模式, 不支持触摸,会自动会落到点击事件, 点击显示为 Click
F12打开开发者工具, 点击模拟手机/平板, 需要F5刷新页面重新读取是否为触摸设备, 点击无反应, 长按显示为