判断元素是否获取焦点
在 JavaScript/React 中判断一个特定 class 的元素是否处于焦点状态,可以通过以下几种方式实现:
原生 JavaScript 方法
// 获取第一个具有 overviewUndoBtn 类的元素
const element = document.querySelector('.overviewUndoBtn');// 检查是否获得焦点
if (element && document.activeElement === element) {console.log('overviewUndoBtn 元素当前获得焦点');
} else {console.log('overviewUndoBtn 元素未获得焦点');
}
React 方法(使用 ref)
如果你在 React 组件中需要检查:
import { useRef, useEffect } from 'react';function MyComponent() {const undoBtnRef = useRef(null);useEffect(() => {const checkFocus = () => {if (document.activeElement === undoBtnRef.current) {console.log('按钮当前获得焦点');// 执行相关操作}};// 可以添加事件监听来实时检测const btn = undoBtnRef.current;btn?.addEventListener('focus', checkFocus);btn?.addEventListener('blur', checkFocus);return () => {btn?.removeEventListener('focus', checkFocus);btn?.removeEventListener('blur', checkFocus);};}, []);return (<button className="overviewUndoBtn"ref={undoBtnRef}>撤销按钮</button>);
}
更完整的 React 钩子实现
可以创建一个自定义钩子来复用这个逻辑:
import { useRef, useState, useEffect } from 'react';function useFocusStatus(className) {const [hasFocus, setHasFocus] = useState(false);const elementRef = useRef(null);useEffect(() => {const element = elementRef.current || document.querySelector(`.${className}`);if (!element) return;const handleFocus = () => setHasFocus(true);const handleBlur = () => setHasFocus(false);element.addEventListener('focus', handleFocus);element.addEventListener('blur', handleBlur);// 初始检查if (document.activeElement === element) {setHasFocus(true);}return () => {element.removeEventListener('focus', handleFocus);element.removeEventListener('blur', handleBlur);};}, [className]);return { hasFocus, elementRef };
}// 使用示例
function MyComponent() {const { hasFocus, elementRef } = useFocusStatus('overviewUndoBtn');return (<div><button className="overviewUndoBtn" ref={elementRef}>撤销按钮</button><p>按钮焦点状态: {hasFocus ? '已获取' : '未获取'}</p></div>);
}
注意事项
-
多个元素:如果有多个元素都有
overviewUndoBtn
类,querySelector
只会返回第一个,如果需要检查所有,使用querySelectorAll
并遍历 -
动态元素:如果元素是动态加载的,可能需要使用 MutationObserver 来检测 DOM 变化
-
React 18 Strict Mode:在开发模式下,useEffect 可能会执行两次,这是正常现象
-
无障碍考虑:焦点状态对于键盘用户很重要,确保焦点样式可见
-
TypeScript 类型:如果需要类型安全,可以添加适当的类型注解
// 为自定义钩子添加类型
function useFocusStatus(className: string): {hasFocus: boolean;elementRef: React.RefObject<HTMLElement>;
} {// ...实现同上
}