React TypeScript项目onBlur事件Chrome生效但Safari不生效问题求助
React TypeScript Safari下onBlur事件兼容问题修复方案
问题根因
- 你为upButton设置了
tabIndex="-1",Safari与Chrome对该属性的焦点行为实现存在差异:Chrome中点击tabIndex="-1"的元素会临时获得焦点,离开时触发blur事件;但Safari默认不会为点击的tabIndex="-1"按钮分配焦点,因此onBlur事件完全不会触发。 - 即便元素获得焦点,Safari下点击页面非交互空白区域时,也不会主动移除当前元素的焦点状态,同样不会触发
blur事件。
可行修复方案
方案1:全局点击事件监听(全浏览器兼容,优先推荐)
不依赖元素本身的blur事件,在错误提示弹出时给document绑定一次性点击监听,判断点击目标是否在upButton外,符合条件则执行隐藏逻辑:
upButton() { let currentValue = this.props.value; if (currentValue === this.props.max) { this.setState({ showSoftError: true, showHardError: true }); // 异步绑定避免当前点击事件冒泡触发判断 setTimeout(() => { const handleOuterClick = (e: MouseEvent) => { const upBtn = document.querySelector('.spinner-control-up'); if (upBtn && !upBtn.contains(e.target as Node)) { this.drawResult(); document.removeEventListener('click', handleOuterClick); } }; document.addEventListener('click', handleOuterClick); }, 0); } if (currentValue < this.props.max && !this.props.disabled) { currentValue++; this.drawResult(); this.onChange(currentValue); } }
方案2:调整tabIndex配置
将upButton的tabIndex="-1"改为tabIndex="0",让按钮可以正常获得焦点,即可在Safari下正常触发blur事件。如果不需要支持Tab键聚焦该按钮,可以额外绑定keydown事件拦截Tab操作即可。
方案3:组件全局监听外部点击
如果组件有多个需要判断外部点击的场景,可以在组件挂载时给document绑定mousedown监听,统一判断点击区域是否在组件外,符合条件则重置错误状态,适合复用性高的通用组件。
内容的提问来源于stack exchange,提问作者Nhan Nguyen
相关产品推荐
相关产品推荐

