如何在输入框blur事件中获取下一个获得焦点的元素
解决输入框失焦时判断下一个聚焦元素的问题
你遇到的这个问题其实是blur事件的常见时机坑,我帮你梳理清楚逻辑并给出能覆盖所有场景的解决方案:
核心问题:blur事件的触发顺序限制
当输入框触发blur事件时,新的焦点元素还没完成聚焦流程,所以直接访问e.relatedTarget经常会得到null(尤其是点击普通文本、div这类默认不可聚焦的元素时)。这时候需要换一种方式来获取最终的焦点状态。
可行方案:延迟获取document.activeElement
利用setTimeout把获取焦点元素的逻辑放到事件循环的下一轮,等浏览器完成焦点切换后再取值,就能准确拿到下一个聚焦的元素了。修改你的代码如下:
handleBlurEvent(e) { // 先确认当前失焦的是目标搜索输入框 const searchInput = e.target.closest('.summary__search-input'); if (!searchInput) return; // 延迟0毫秒,让浏览器完成焦点切换后再获取 setTimeout(() => { const nextFocusedElement = document.activeElement; // 替换成你的搜索按钮实际选择器,比如'.summary__search-btn' const searchButton = document.querySelector('.your-search-button-selector'); // 判断:如果下一个聚焦元素不是搜索按钮,就执行行为b if (nextFocusedElement !== searchButton) { searchInput.value = ""; if (searchInput.animation) { searchInput.animation.reverse(); } } // 如果是搜索按钮,什么都不做,交给按钮自身的监听器处理行为a }, 0); }
针对你的场景验证:
- 场景1/3:点击搜索按钮:失焦后焦点落在搜索按钮上,
nextFocusedElement等于按钮元素,不会执行清空输入框的逻辑,按钮的独立监听器正常触发行为a,完全符合需求。 - 场景2:点击输入框外部:如果点击的是不可聚焦元素,
nextFocusedElement会是body;如果点击的是其他可聚焦元素(比如另一个输入框),也能准确识别,只要不是搜索按钮,就执行行为b。
补充说明relatedTarget的使用场景
其实e.relatedTarget在部分场景下是有效的——比如从输入框直接聚焦到另一个可聚焦元素(按钮、其他输入框)时,它能直接返回目标元素。但如果点击的是不可聚焦元素,它就会返回null,这时候document.activeElement会更可靠(通常是body)。所以结合setTimeout+document.activeElement的方案能覆盖所有场景。
内容的提问来源于stack exchange,提问作者NickW
相关产品推荐
相关产品推荐

