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

Blazor Server模态框如何设置首个输入元素自动获取焦点?

解决Blazor Server模态框打开时首个输入框自动获焦问题

你遇到的autofocus无效问题,本质是因为模态框未打开时,BodyTemplate里的输入框要么还没被渲染到DOM中,要么处于隐藏状态——autofocus属性仅在元素首次插入可见DOM时才会触发自动聚焦,所以直接加属性没用。下面给两种可行的解决方案:

方案一:通过ElementReference+JS互操作手动设置焦点

这种方法直接获取第一个输入框的引用,在模态框完全显示后调用JS聚焦:

  1. 在组件中注入IJSRuntime,给第一个输入框添加@ref引用:
@inject IJSRuntime JS

<Modal @ref="modalMultipleSerialNumbers" Title="Add/Change Multiple Serial Numbers" UseStaticBackdrop="true" Size="ModalSize.ExtraLarge">
<BodyTemplate>
    @for (var i = 0; i < SD.MaxNumberOfMultiples; i++)
    {
        var count = i;
        @if (count == 0)
        {
            <!-- 给第一个输入框添加ElementReference -->
            <input @bind="@MulipleSerialNumbers[count]" @ref="firstSerialInput" class="col-4 m-1" />
        }
        else
        {
            <input @bind="@MulipleSerialNumbers[count]" class="col-4 m-1" />
        }
    }
</BodyTemplate>
<FooterTemplate>
    <Button Color="ButtonColor.Secondary" @onclick="OnClearModalClick">Clear list of Serial Numbers</Button>
    <Button Color="ButtonColor.Primary" @onclick="OnSaveModalClick">Save list of Serial Numbers</Button>
</FooterTemplate>
</Modal>
  1. 在代码块中处理模态框打开逻辑,显示后触发聚焦:
@code {
    private Modal? modalMultipleSerialNumbers;
    private ElementReference firstSerialInput;
    private string[] MulipleSerialNumbers = new string[SD.MaxNumberOfMultiples];

    // 打开模态框的方法(根据你的实际调用逻辑调整)
    public async Task OpenMultiSerialModal()
    {
        // 先显示模态框
        await modalMultipleSerialNumbers!.ShowAsync();
        // 等待模态框DOM渲染完成(短延迟确保元素已存在)
        await Task.Delay(10);
        // 调用JS函数聚焦
        await JS.InvokeVoidAsync("focusElement", firstSerialInput);
    }

    private void OnClearModalClick()
    {
        // 你的清空逻辑
        Array.Clear(MulipleSerialNumbers, 0, MulipleSerialNumbers.Length);
        StateHasChanged();
    }

    private void OnSaveModalClick()
    {
        // 你的保存逻辑
        modalMultipleSerialNumbers!.CloseAsync();
    }
}
  1. 在wwwroot/index.html的<body>末尾添加JS函数:
<script>
    function focusElement(element) {
        element.focus();
    }
</script>

方案二:监听模态框显示事件(适配Bootstrap类模态框)

如果你的模态框组件基于Bootstrap,可以通过监听shown.bs.modal事件(模态框完全显示后触发)来自动聚焦:

  1. 给模态框添加唯一Id,并实现IAsyncDisposable用于清理JS资源:
@inject IJSRuntime JS
@implements IAsyncDisposable

<Modal @ref="modalMultipleSerialNumbers" Id="multiSerialModal" Title="Add/Change Multiple Serial Numbers" UseStaticBackdrop="true" Size="ModalSize.ExtraLarge">
<!-- 输入框和按钮代码同之前 -->
</Modal>
  1. 在代码块中导入JS模块并设置事件监听:
@code {
    private Modal? modalMultipleSerialNumbers;
    private string[] MulipleSerialNumbers = new string[SD.MaxNumberOfMultiples];
    private IJSObjectReference? jsModule;

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            // 导入自定义JS模块
            jsModule = await JS.InvokeAsync<IJSObjectReference>("import", "./scripts/modal-focus.js");
            // 传入模态框ID设置监听
            await jsModule.InvokeVoidAsync("setupModalAutoFocus", "multiSerialModal");
        }
    }

    // 清理JS模块资源
    async ValueTask IAsyncDisposable.DisposeAsync()
    {
        if (jsModule is not null)
        {
            await jsModule.DisposeAsync();
        }
    }

    // 其他方法同上...
}
  1. 在wwwroot/scripts/下新建modal-focus.js文件:
export function setupModalAutoFocus(modalId) {
    const modal = document.getElementById(modalId);
    // 监听模态框完全显示事件
    modal.addEventListener('shown.bs.modal', function () {
        // 找到模态框内第一个输入框并聚焦
        const firstInput = this.querySelector('input:first-of-type');
        if (firstInput) {
            firstInput.focus();
        }
    });
}

两种方案都能解决你的问题,方案一更直接,方案二更贴合Bootstrap模态框的原生行为,根据你的组件实际情况选择即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 15:15:42