如何将焦点设置到 InputText 元素?

Uwe*_*eim 12 blazor blazor-server-side

使用Microsoft docs 中示例,我尝试以编程方式将焦点设置为输入元素。

不幸的是,该示例使用了标准,<input type="text">而我想将其用于InputTextelement

Microsoft 示例使用了一种扩展方法,该方法采用ElementReference

public static Task Focus(this ElementReference elementRef, IJSRuntime jsRuntime)
{
    return jsRuntime.InvokeAsync<object>(
        "exampleJsFunctions.focusElement", 
        elementRef);
}
Run Code Online (Sandbox Code Playgroud)

使用InputText,我认为无法获得这样的ElementReference.

提供我自己的Focus()重载InputText而不是编译但没有显示视觉结果。所以我一无所知。

我的问题

如何以编程方式将焦点设置为InputText元素?

Mmm*_*Mmm 32

对于 .NET 6 和 .NET 7:

在您的代码中,创建一个 InputText 变量,可以在 @code 中,也可以在代码后面:

private InputText inputTextForFocus;

在 BlazorInputText组件中,引用该变量:

<InputText @ref=inputTextForFocus>

然后,在代码中的适当位置,您可以访问Element的底层InputText并调用FocusAsync(). 注释Element可以为空。

例如,要将焦点设置为启动:

protected override async Task OnAfterRenderAsync(bool firstRender)
{
    if (inputTextForFocus?.Element != null)
    {
        await inputTextForFocus.Element.Value.FocusAsync();
    }
}
Run Code Online (Sandbox Code Playgroud)

信用到期的信用: https://www.youtube.com/watch ?v=9Q7cXdylU7k

  • 我必须添加 if (inputTextForFocus != null) 因为在第一次调用 OnAfterRenderAsync 时它是 null,但在后来的调用中它不是。 (2认同)

Maj*_*jor 18

.NET5 中,它会简单得多:

<button @onclick="() => textInput.FocusAsync()">Set focus</button>
<input @ref="textInput"/>
Run Code Online (Sandbox Code Playgroud)

注意:此功能是在.NET5 Preview 8 中引入的,因此在最终版本发布之前可能会发生变化!

另外值得一提的是,在.NET5 RC1 中 JavaScript 隔离是通过JS Module export/import引入的。所以如果你仍然需要使用 JS 互操作,不要污染window对象。

更新: .NET 5 已发布,此功能未更改。

还发现了一个很酷的Nuget 包,它可以为您做一些方便的 JS 技巧,例如:聚焦以前活跃的元素而无需使用@ref。请参阅此处的文档。

  • 看来您是您提到的 NuGet 包的所有者。正确的? (2认同)

Pio*_*r L 15

您可以添加id参数InputText并修改您的Focus方法和 JavaScript 代码。

public async Task Focus(string elementId)
{
    await JSRuntime.InvokeVoidAsync("exampleJsFunctions.focusElement", elementId);
}
Run Code Online (Sandbox Code Playgroud)
focusElement: function (id) {
    const element = document.getElementById(id); 
    element.focus();
}
Run Code Online (Sandbox Code Playgroud)

注意:这与其说是一个合适的解决方案,不如说是一种解决方法,但 Blazor 似乎并不直接支持它。


Rya*_*ele 5

我能够通过在 Host.chtml 文件中直接输入 JavaScript 来完成此操作(您也可以像演练建议的那样添加 .js 文件):

<script type="text/javascript">
    window.exampleJsFunctions = {
        focusElement: function (element) {
            element.focus();
        }
    }
</script>
Run Code Online (Sandbox Code Playgroud)

接下来,在扩展文件中,我添加了扩展(注意:我重命名FocusFocusAsync因为命名标准:

public static async Task FocusAsync(this ElementReference elementRef, IJSRuntime jsRuntime)
{
    await jsRuntime.InvokeVoidAsync(
        "exampleJsFunctions.focusElement", elementRef);
}
Run Code Online (Sandbox Code Playgroud)

然后在 razor 页面(或组件)中,注入IJSRuntime,添加ElementReference并将其绑定到您要聚焦的元素(注意:方法名称已更改以遵守命名标准):

@inject IJSRuntime JSRuntime
@using JsInteropClasses

<input @ref="username" />
<button @onclick="SetFocusAsync">Set focus on username</button>

@code {
    private ElementReference username;

    public async Task SetFocusAsync()
    {
        await username.FocusAsync(JSRuntime);
    }
}
Run Code Online (Sandbox Code Playgroud)

  • InputText 不是 ElementReference,因此此实现对此不起作用。 (2认同)

Pet*_*ris 5

这是将解决方案组件化的简单方法

例子

@page "/"
Enter your name
<input @ref=ReferenceToInputControl />
<AutoFocus Control=ReferenceToInputControl/>

@code {
  ElementReference ReferenceToInputControl;
}
Run Code Online (Sandbox Code Playgroud)

这是 .NET 7 的代码

@code {
    [Parameter]
    public ElementReference Control { get; set; }

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
            await Control.FocusAsync();
    }
}
Run Code Online (Sandbox Code Playgroud)

如果您使用的是 .NET 6 或更早版本

@inject IJSRuntime JSRuntime
@code {
    [Parameter]
    public ElementReference Control { get; set; }

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
            await JSRuntime.InvokeVoidAsync("BlazorUniversity.setFocus", Control);
    }
}
Run Code Online (Sandbox Code Playgroud)

在您的页面中引用以下 JavaScript。

var BlazorUniversity = BlazorUniversity || {};
BlazorUniversity.setFocus = function (element) {
    element.focus();
};
Run Code Online (Sandbox Code Playgroud)