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 ============================================================= ...
随机推荐
- XML_DTD_20200415
<!-- xml的注释写法 --> 格式良好的xml语言必须具备的几个条件 1.必须有xml声明语句,声明版本号与编码字符集 2.必须有且仅有一个根元素 3.标签大小写敏感 4.属性值 ...
- "蔚来杯"2022牛客暑期多校训练营1 C.Grab the Seat!
C.Grab the Seat! 题目链接 https://ac.nowcoder.com/acm/contest/33186/C 题目大意 1.二维平面中,(0,1) - (0,m)为屏幕 2.有n ...
- ABP vNext微服务架构详细教程——项目部署
1. 基础配置 在之前的文章中,我们已经配置了Kubernetes集群并安装了管理工具Kubesphere,文章地址为:https://mp.weixin.qq.com/s/MgpdMv5A-fYxN ...
- 制作带curl命令的容器
创建一个容器,启动后使用curl命令请求指定的地址 方法一.固定的地址,创建Dockerfile前先修改entrypoint.sh里的地址 vi entrypoint.sh#! /bin/bashcu ...
- 西电oj135题 拼数字并排序
类别综合 时间限制 1S 内存限制 1000Kb 问题描述 对于输入的字符串(只包含字母和数字),将其中的连续数字拼接成整数,然后将这些整数按从大到小顺序输出.例如字符串"abc123d5e ...
- 2019年居然还出版了一本ASP学习的书籍
ASP+Dreamweaver动态网站开发(第2版)孙更新,宾晟,李晓娜 著 内容简介 <ASP+Dreamweaver动态网站开发(第2版)>详细介绍了ASP的脚本语言基础.ASP的相关 ...
- python使用zipfile压缩文件,包括空目录
zipfile压缩文件.包括空目录 # !/usr/bin/python import os import zipfile def zipdir(dirPath=None, zipFilePath=N ...
- mysql 以自增id等于某个random()函数算出的值为条件查出两条数据
SELECT id FROM users WHERE id = FLOOR( rand() * ( (SELECT max(id) FROM users) - (SELECT min(id) FROM ...
- (新手向)在Linux中使用VScode编写 "Hello,world"程序,并编写测试-Ubuntu20.4
本文意在帮助 Go 语言初学者在 Linux环境下编写自己的第一个Golang程序 难点主要在 VScode 中 Go 插件的下载 与 go.mod 以及编译运行和 第一个Go测试程序的使用 前提准备 ...
- 第六章 C控制语句:分支和跳转
6.1if语句 程序 #define _CRT_SECURE_NO_WARNINGS 1 //coladays.c -- 求出温度低于零度的天数 #include<stdio.h> int ...