自定义下拉组件:外层div的onfocusout事件异常触发问题
解决Blazor自定义下拉组件焦点误触发关闭的问题
问题核心是focusout事件的冒泡特性:当焦点从输入框切换到内部复选框时,会触发外层div的focusout,但此时焦点仍在组件内部,不该关闭下拉列表。
解决方案:判断焦点转移目标是否在组件内
修改HidedicList方法,通过事件的relatedTarget属性检查焦点是否还停留在当前组件的DOM元素内,只有当焦点完全离开组件时才执行关闭逻辑。
1. 更新Blazor后端方法
如果是Blazor Server,可直接通过DOM交互判断:
private void HidedicList(FocusEventArgs e) { var target = e.RelatedTarget as Element; var outerDiv = document.GetElementById("vendor-select-container"); if (target == null || !outerDiv.Contains(target)) { showhide = "hidden"; // 替换为你的隐藏类名 StateHasChanged(); } }
如果是Blazor WebAssembly,需要注入IJSRuntime配合JS辅助判断:
[Inject] private IJSRuntime JSRuntime { get; set; } private async void HidedicList(FocusEventArgs e) { var isInside = await JSRuntime.InvokeAsync<bool>("isElementInsideContainer", e.RelatedTarget, "vendor-select-container"); if (!isInside) { showhide = "hidden"; StateHasChanged(); } }
2. 修改前端HTML结构
给外层div添加唯一id,确保所有可交互元素都包含在其中:
<div id="vendor-select-container" @onfocusout="@((e) => HidedicList(e))"> <input for="toggleVendors" class="form-control label-toggle" placeholder="Vendor Information" @onchange="selectedValue" @onfocus="@((e) => ShowdicList(e))" /> <input type="checkbox" id="toggleVendors" class="hidden-checkbox" > <div id="diclist" class="@showhide"> <ul> @foreach (var item in (Dictionary<int,string>)this.selectListItems.Items) { <li><input type="checkbox" id="@item.Key" @onchange="@((e) => CheckboxChanged(e, @item.Key))" value="@item.Value" /> @item.Value</li> } </ul> </div> </div>
3. 添加JS辅助函数(仅WebAssembly需要)
在wwwroot目录下的JS文件中添加以下函数:
window.isElementInsideContainer = function(element, containerId) { const container = document.getElementById(containerId); if (!element || !container) return false; return container.contains(element); };
关键说明
relatedTarget指向焦点即将转移到的元素,若该元素是外层div的子元素,说明焦点仍在组件内,不执行关闭逻辑。- 确保所有可聚焦元素(输入框、复选框)都包含在外层div中,避免误判焦点离开。
内容的提问来源于stack exchange,提问作者bilpor
相关产品推荐
相关产品推荐

