Blazor入门100天 : 自做一个支持长按事件的按钮组件

好长时间没继续写这个系列博客了, 不知道大家还记得我吗? 话不多说,直接开撸.

配套源码
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刷新页面重新读取是否为触摸设备, 点击无反应, 长按显示为

  • 9
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Blazor自带了一些内置的组件,这些组件使得开发人员可以更快地构建交互式的用户界面。以下是Blazor自带的一些常用组件: 1. `<Router>`组件:用于实现基于路由的导航,可以在应用程序中创建多个页面,并使用不同的URL路径进行导航。 2. `<RouteView>`组件:与`<Router>`组件配合使用,用于根据当前URL路径加载相应的页面组件。 3. `<NavLink>`组件:用于生成带有导航功能的超链接,可以设置活动状态样式以及导航到指定的URL路径。 4. `<Form>`组件:用于创建表单,可以包含各种输入控件和验证规则,方便进行表单数据的收集和提交。 5. `<InputText>`、`<InputCheckbox>`等输入控件组件:用于创建各种类型的输入控件,如文本框、复选框等。 6. `<Select>`、`<Option>`组件:用于创建下拉选择框,可以动态生成选项列表,并实现选项的绑定和选择。 这些内置组件可以通过在Blazor应用程序中引用相应的命名空间来使用,例如`Microsoft.AspNetCore.Components`和`Microsoft.AspNetCore.Components.Forms`等。可以在Blazor的官方文档和教程中找到更多关于这些组件的详细信息和用法。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [Blazor 组件入门指南](https://blog.csdn.net/farway000/article/details/125650695)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Densen2014

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值