如何在Blazor/C#中不使用JavaScript,按下ESC键时取消按钮焦点?
在Blazor中实现无JS依赖的ESC关闭Tooltip功能
我正在Blazor框架中开发一个Tooltip组件,需求是当按钮处于焦点状态时按下ESC键,Tooltip会消失。目前已通过JavaScript实现该功能,但希望移除对JS的依赖。
当前实现代码
@inject IJSRuntime JSRuntime <button @onclick="ToggleTooltip">test</button> <div role="tooltip" @ref="tooltip" tabindex="0" @onkeydown="CloseTooltip"> Password Rules: </div> <p>test</p> @code { ElementReference tooltip; bool showTooltip = false; void ToggleTooltip() { showTooltip = !showTooltip; if (showTooltip) { tooltip.FocusAsync(); } } async Task CloseTooltip(KeyboardEventArgs e) { if (e.Key == "Escape") { showTooltip = false; await JSRuntime.InvokeVoidAsync("Blurred", tooltip); await InvokeAsync(StateHasChanged); } } } <script> window.Blurred = function(element) { element.blur(); }; </script> <style> * { margin: 0; padding: 0; } [role="tooltip"] { margin-top: .75rem; display: none; position: absolute; background: black; color: white; } [role="tooltip"]:before { margin-top: -7px; content: ""; border: 7px solid transparent; border-bottom-color: #000; border-top-width: 0; position: absolute; } button:hover + [role="tooltip"], button:focus + [role="tooltip"], [role="tooltip"]:focus { display: block; } </style>
无JS依赖的解决方案
核心是用Blazor内置的焦点管理API替代JS操作,同时通过状态绑定控制Tooltip显示,避免依赖元素的:focus状态来控制UI。
修改后的完整代码
<button @onclick="ToggleTooltip" @ref="triggerButton">test</button> <div role="tooltip" @ref="tooltip" tabindex="0" @onkeydown="CloseTooltip" class="@(showTooltip ? "show" : "")"> Password Rules: </div> <p>test</p> @code { ElementReference tooltip; ElementReference triggerButton; bool showTooltip = false; void ToggleTooltip() { showTooltip = !showTooltip; if (showTooltip) { _ = tooltip.FocusAsync(); } else { _ = triggerButton.FocusAsync(); } } async Task CloseTooltip(KeyboardEventArgs e) { if (e.Key == "Escape") { showTooltip = false; await triggerButton.FocusAsync(); } } } <style> * { margin: 0; padding: 0; } [role="tooltip"] { margin-top: .75rem; display: none; position: absolute; background: black; color: white; } [role="tooltip"]:before { margin-top: -7px; content: ""; border: 7px solid transparent; border-bottom-color: #000; border-top-width: 0; position: absolute; } button:hover + [role="tooltip"], button:focus + [role="tooltip"], [role="tooltip"]:focus, [role="tooltip"].show { display: block; } </style>
关键修改说明
- 移除JS依赖:删掉
IJSRuntime注入和JS脚本,改用triggerButton.FocusAsync()把焦点移回触发按钮,自动让Tooltip失去焦点。 - 状态驱动UI:给Tooltip绑定
class="@(showTooltip ? "show" : "")",通过布尔值直接控制显示状态,不再完全依赖CSS选择器。 - 简化更新逻辑:
showTooltip变更后Blazor会自动刷新UI,不需要手动调用StateHasChanged。 - 保留原有交互:保留了hover、focus等触发逻辑,确保原有用户体验不变。
内容的提问来源于stack exchange,提问作者Daphne Zwuup
相关产品推荐
相关产品推荐

