最开始想实现一个功能,点击img图标后给出购物下拉框CartDropdown,当img及CartDropdown失去焦点时隐藏CartDropdown。

最开始的核心代码如下:

export default function Cart() {
const [isCartOpen, setIsCartOpen] = useState(false) function clickHandler() {
setIsCartOpen(!isCartOpen)
} function closeCartDropdown() {
if(!document.querySelector('#cart').contains(document.activeElement)) {
setIsCartOpen(false)
}
} return (
<div id="cart" className="relative" onBlur={closeCartDropdown}>
<div tabIndex={0} onClick={clickHandler} className='relative hover:-translate-y-0.5 active:translate-y-0 transition-transform cursor-pointer'>
<img className='h-14' src="/src/assets/images/shopping_bag.png" alt="shopping bag" />
<span className='Z-10 text-2xl font-bold absolute left-1/2 -translate-x-1/2 -translate-y-2/3' style={{top:'70%'}}>4</span>
</div>
{
<CartDropdown isCartOpen={isCartOpen}/>
}
</div>
)
}

这个版本的代码中在onBlur回调中使用document.activeElement函数想要获取当前聚焦的元素,之后通过判断聚焦的元素是cart组件内的来判断是否需要隐藏cartDropdown,但这里document.activeElement返回的都是body元素。

后面我加入了onFocus函数,并在其中获取document.activeElement却能返回正确的结果,并且是先触发onBlur再触发onFocus函数。这样就可以确定,在之前的元素失去焦点时,onBlur函数被调用,此时没有焦点因此默认给在body上;之后onFocus函数执行,此时新元素获得焦点,因此可以正常获取聚焦结果。

因此在onBlur中想要正确获取聚焦元素,应该在onFocus函数调用后,所以可以使用异步函数来完成这一点。我选取setTimeout来进行异步操作,并且成功在onBlur函数中获取到了正确的document.activeElement值。

function closeCartDropdown() {
setTimeout(() => {
if(!document.querySelector('#cart').contains(document.activeElement)) {
setIsCartOpen(false)
}
}, 0)
}

备注:传统html中blur事件是不能冒泡的,但react中进行了特殊的处理成功模拟了冒泡,因此可以实现子组件失去焦点,调用父组件回调函数的效果。

最新文章

  1. 《Django By Example》第五章 中文 翻译 (个人学习,渣翻)
  2. php面向对象编程(三)
  3. 使用Powershell链接到Office 365
  4. ubuntu16041,安装opencv3.1.0
  5. JavaScript 事件——“事件类型”中“复合事件”和“变动事件”的注意要点(转)
  6. OC中类的扩展介绍
  7. Android下结束进程的方法
  8. 跟我学LFS LiveUSB制作
  9. webform 简单的服务器控件。
  10. RobotFramework 自定义Library
  11. 新项目架构从零开始(三)------基于简单ESB的服务架构
  12. JUnit4.8.2来源分析-2 org.junit.runner.Request
  13. Python tools used for file name devision
  14. POJ 2373 Yogurt factory
  15. expdp导出文件,ORA-01555: 快照过旧: 回退段号 716
  16. The client and server cannot communicate, because they do not possess a common algorithm
  17. Jquery UI 中的datepicker() ,获取日期后的回调函数onClose()
  18. sendmail 发送邮件 zabbix 自定义报警
  19. mysql数据库----索引原理与慢查询优化
  20. Unity 5.1+ Assertion Library (断言库)

热门文章

  1. 正向代理和反向代理和spring的动态代理模式有几种?默认是那种?如何切换?
  2. SDN实验环境配置
  3. Python第五章实验报告
  4. 【StoneDB 模块介绍】服务器模块
  5. 中文数据导入到hive,出现乱码
  6. Windows10系统快速安装.NET Framework3.5的方法&amp;常见问题处理方法
  7. For循环用法-打印乘法表
  8. OSPF与ISIS比较
  9. JDK1.8中的时间处理API
  10. 关于前端JS的一些常用方法和知识