React onBlur回调中使用document.activeElement返回body解决方案
最开始想实现一个功能,点击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中进行了特殊的处理成功模拟了冒泡,因此可以实现子组件失去焦点,调用父组件回调函数的效果。
React onBlur回调中使用document.activeElement返回body解决方案的更多相关文章
- JS中Date.parse方法返回NaN解决方案
Date.parse()方法: //将时间字符串转换为秒数 var date_str = '2013-12-3 18:32:00'; alert(date_str.replace(/-/g,'/')) ...
- document.activeElement 过滤选择文件弹窗导致的页面失焦
在线考试页面,常常需要检测用户是否作弊. 一般是监听页面是否失焦的方式,而失焦的方式有很多种,比如QQ弹窗,切换页面,切换程序,input文件上传选择文件等 选择文件是正常情况,这种情况下需要过滤 本 ...
- React 函数组件中对window添加事件监听resize导致回调不能获得Hooks最新状态的问题解决思路
React 函数组件中对window添加事件监听resize导致回调不能获得Hooks最新状态的问题解决思路 这几天在忙着把自己做的项目中的类组件转化为功能相同的函数组件,首先先贴一份该组件类组件的关 ...
- jQuery:在一个回调中处理多个请求
我曾经为Mozilla Developer Network 开发一个新功能,它需要加载一个基本的脚本文件的同时加载一个JSON请求.因为我们使用的是jQuery,意味着要使用 jQuery.getSc ...
- HTML:document.activeElement
今天遇到一个很郁闷的问题: document.activeElement获取当前获得焦点的元素,在chrome总是得到body,后来经过试验得到结果如下: document.activeElement ...
- JavaScript中的document.cookie的使用
转:http://blog.csdn.net/liuyong0818/article/details/4807473 我们已经知道,在 document 对象中有一个 cookie 属性.但是 Coo ...
- 用document.getElementsByTagName()返回的真的是数组吗?
document.getElementsByTagName()返回的真的是数组吗? 这是这几天开发中遇到的问题. 一个如下的HTML结构: <ul> <li> <li&g ...
- js中的referrer使用,返回上一页
js完整代码: <script language="javascript"> var refer=document. referrer ; document.g ...
- 使用domain模块捕获异步回调中的异常
和其他服务器端语言相比,貌似node.js 对于异常捕捉确实非常困难. 首先你会想到try/catch ,但是在使用过程中我们会发现并没有真正将错误控制在try/catch 语句中. 为什么? 答案是 ...
- 【转】Andorid中Intent的使用-返回数据给上一个活动
第一个Activity A启动另外一个Activity B,B返回数据给A ============================================================= ...
随机推荐
- Android studio SDK配置
因为两个月前装过一次Android studio,所以完全按教程走不通. 已有Android studio的情况下,先在configue下配置SDK的位置,这里可能会报一个错,platforms不存在 ...
- jsp执行流程
Jsp执行流程 jsp -----java ----class E: \student\apache-tomcat-8.5.30\work\Catalina\localhost\JspProject ...
- 遇到 https://packetlife.net/
"I have never let my schooling interfere with my education." --Mark Twain
- 初始化时使window 全屏 且显示任务栏 wpf
void IniWindowFullScreemAndDisplayTaskbar() { this.Width = SystemParameters.FullPrimaryScreenWidth; ...
- Go_day01
Go基础语法 注释 注释是为了增强代码的可读性,不会参与程序的一切功能, go语言注释分为单行注释与多行注释 单行注释 //双斜杠 每行都要添加 // 多行注释 /* */ 一次标记多行注释输入 pa ...
- BeanFactory与FactoryBean区别
1. BeanFactory BeanFactory,以Factory结尾,表示它是一个工厂类(接口),用于管理Bean的一个工厂.在Spring中,BeanFactory是IOC容器的核心接口,也是 ...
- table control的最小高度
标准的表维护和不通过向导建的table control最小显示行是2. 通过向导建立的table control最小显示行是4. 前台没有任何能看出来的配置差异. 有个隐藏的最小显示行,只有把屏幕下来 ...
- SimpleITK和nibable读取nii文件
import SimpleITK as sitk path = 'nii全路径' nii_obj = sitk.GetArrayFromImage(sitk.ReadImage(path)) #sha ...
- fatal: unable to access ' ' OpenSSL SSL_read: Connection was reset, errno 10054
描述: git clone ...时报错 fatal: unable to access 'https://github.com/github-eliviate/papers.git/': OpenS ...
- Qt 学习笔记 - 第三章 - Qt的三驾马车之一 - 串口编程 + 程序打包成Windows软件
Qt 学习笔记全系列传送门: Qt 学习笔记 - 第一章 - 快速开始.信号与槽 Qt 学习笔记 - 第二章 - 添加图片.布局.界面切换 [本章]Qt 学习笔记 - 第三章 - Qt的三驾马车之一 ...