封闭开发了一段时间重感冒了,本来应该整理为几篇文章,康复后发现细节已淡忘,记录为几个不同的片段吧
e.preventDefault()
背景:可模拟ant-design的select组件,在输入框有值显示下拉选择列表的基础上,当输入框为空的时候,显示10条之前的搜索历史记录列表
/**
* 自定义钩子:点击页面任何位置时触发回调函数
* @param onClickAway - 点击页面任何位置时需要执行的回调函数
* @param ref - React 引用对象,指向需要排除点击事件的 DOM 元素
*/
const useClickAnywhere = (onClickAway: () => void, ref: RefObject<HTMLElement>): void => {
useEffect(() => {
// 点击事件处理函数
const handleClickOutside = (event: MouseEvent): void => {
if (ref.current && !ref.current.contains(event.target as Node)) {
onClickAway();
}
};
// 绑定点击事件
document.addEventListener('mousedown', handleClickOutside);
// 组件卸载时移除事件监听
return (): void => {
document.removeEventListener('mousedown', handleClickOutside);
};
}, [onClickAway, ref]);
};
export default useClickAnywhere;
可是子域嵌的Iframe,无法监听Iframe的点击事件, 导致子域弹窗一直尴尬的在那儿。和其中一位子域研发沟通后,他给我传了click事件,message监听到之后,处理弹窗消失。但是每个子域都需要这样做,每个子域研发不同,有点麻烦,e.preventDefault()出现了!!
e.preventDefault() 可以阻止某些特定的默认行为,但并不能阻止所有事件的触发。
e.preventDefault()可以用于阻止onPressEnter事件的默认行为,例如在表单中按下回车键时阻止表单提交。e.preventDefault()可以用于阻止onBlur事件的默认行为,例如在某些情况下阻止输入框失去焦点。
所以只要在列表的最外层元素上加上onMouseDown={(e: React.MouseEvent<HTMLDivElement>) => e.preventDefault()}这段代码,就可以实现点击弹窗区域,弹窗不消失,点击弹窗之后,触发onBlur,弹窗消失
举个例子,假设我们有一个输入框和一个按钮,当点击按钮时,阻止输入框失去焦点(阻止 onBlur 事件):
import React, { useRef } from 'react';
import { Input, Button } from 'antd';
const PreventBlurExample = () => {
const inputRef = useRef(null);
const handleMouseDown = (e) => {
e.preventDefault(); // 阻止按钮点击时输入框失去焦点
};
return (
<div>
<Input ref={inputRef} placeholder="Click the button to prevent blur" />
<Button onMouseDown={handleMouseDown}>Prevent Blur</Button>
</div>
);
};
export default PreventBlurExample;
在这个例子中,当点击按钮时,e.preventDefault() 阻止了 onMouseDown 事件的默认行为,从而阻止了输入框的 onBlur 事件。
pointer-events: none
背景:react项目,div包了一个svg元素,div上有个onClick点击事件,本地调试没有问题,pre环境发现点击svg的边缘可以触发onClick,点击svg没有反应。
一开始的解决方法是把svg改为了Img,后来大佬推荐了pointer-events: none;
当时时间紧迫且别人维护的代码又臭又长,没太研究具体原因
猜测可能的原因:
- 事件传播问题:SVG元素可能会阻止事件传播到其父元素(即div),尤其是当SVG内部有自己的一些事件处理逻辑时。即事件在SVG元素上被阻止或中断了。
- SVG默认行为:一些SVG元素可能会有自己的默认行为,阻止了事件的传播或者处理。
解释
CSS pointer-events 属性:
- 在CSS中,
pointer-events: none;的作用是禁用元素的鼠标事件。这意味着,当你把鼠标移动到该元素上时,它不会响应任何鼠标事件(如点击、悬停等)。 -
pointer-events: none;属性使得 SVG 元素不会拦截点击事件。这样,当你点击 SVG 元素时,事件会直接传递给它的父元素(即 div)。