我正在寻找一种方法来检测单击事件是否发生在组件之外,如本文所述。jQuery closest()用于查看单击事件的目标是否将dom元素作为其父元素之一。如果存在匹配项,则单击事件属于其中一个子项,因此不被视为在组件之外
所以在我的组件中,我想在窗口中附加一个点击处理程序。当处理程序启动时,我需要将目标与组件的dom子级进行比较
click事件包含“单击”等属性;路径“;它似乎保存了事件经过的dom路径。我不知道比较什么或者如何最好地遍历它,我想一定有人已经把它放在了一个聪明的实用函数中。。。没有
React 16.3+中的参考用法已更改
下面的解决方案使用ES6并遵循绑定以及通过方法设置ref的最佳实践
要看到它的作用:
- 类实现
- 钩子实现
类实现:
import React,{Component}来自'React';
从“道具类型”导入道具类型;
/**
*当您在组件外部单击时发出警报的组件
*/
导出默认类OutsideAlerter扩展组件{
建造师(道具){
超级(道具);
this.wrapperRef=React.createRef();
this.setWrapperRef=this.setWrapperRef.bind(this);
this.handleClickOutside=this.handleClickOutside.bind(this);
}
componentDidMount(){
document.addEventListener('mousedown',this.handleclickout);
}
组件将卸载(){
document.removeEventListener('mousedown',this.handleclickout);
}
/**
*在元素外部单击时发出警报
*/
handleClickOutside(事件){
if(this.wrapperRef&;!this.wrapperRef.current.contains(event.target)){
警惕(“你在我之外点击了!”);
}
}
render(){
return<;div ref={this.wrapperRef}>;{this.props.children}<;/div>;;
}
}
OutsideAlerter.propTypes={
子项:PropTypes.element.isRequired,
};
钩子实现:
import React,{useRef,useffect}from";“反应”;;
/**
*发出警报的钩子在传递的引用之外单击
*/
功能useOutsideAlerter(参考){
使用效果(()=>{
/**
*在元素外部单击时发出警报
*/
函数handleClickOutside(事件){
if(参考当前和参考当前包含(事件目标)){
警惕(“你在我之外点击了!”);
}
}
//绑定事件侦听器
文件.添加的列表器(“mousedown”,handleClickOutside);
返回()=>{
//在清理时取消绑定事件侦听器
文档。移除EventListener(“鼠标向下”,把手单击外部);
};
},[ref]);
}
/**
*当您在组件外部单击时发出警报的组件
*/
导出默认功能OutsideAlerter(道具){
const wrapperRef=useRef(null);
使用外部报警器(wrapperRef);
return<;div ref={wrapperRef}>;{props.children}<;/div>;;
}