点击模态框外部关闭弹窗,点击内部元素不触发关闭的解决方案
解决模态框内部点击触发关闭的问题
嘿,这个问题我熟!你现在遇到的情况是因为你的判断逻辑只检查了点击目标是不是模态框的容器本身,但点击内部按钮的时候,e.target是按钮元素,不是容器,所以就触发了关闭逻辑。别担心,咱们改一下判断方式就行~
问题根源
你当前的判断条件是:
if (this.DOMArrowBox.current !== e.target) { this.handleClickoutside() }
这个逻辑只对比了点击目标和模态框容器本身,但模态框内部的按钮、图标等子元素都不符合这个条件,所以点击它们时也会触发关闭。
解决方案:使用Element.contains()方法
DOM元素有个原生的contains()方法,它可以判断一个元素是否是另一个元素的后代(包括元素自身)。我们可以用这个方法来检查点击的元素是否在模态框内部,只有点击外部元素时才关闭弹窗。
修改后的代码
首先更新你的点击事件处理函数,同时还要修正生命周期钩子(componentWillMount已经被废弃,而且此时ref还未绑定到DOM元素,换成componentDidMount更安全):
public handleClickoutside() { this.props.showMessage(); } public handleClick = (e) => { // 先确保ref已经关联到DOM元素,再检查点击位置 if (this.DOMArrowBox.current && !this.DOMArrowBox.current.contains(e.target)) { this.handleClickoutside(); } } // 换成componentDidMount,确保ref已经赋值 public componentDidMount() { document.addEventListener("mousedown", this.handleClick, false); } public componentWillUnmount() { document.removeEventListener("mousedown", this.handleClick, false); } render() { return ( <div className={this.props.className} ref={this.DOMArrowBox}> <Social /> <CallMe className="arrow__box-button" open={this.props.open} /> <Close className="arrow-button_close" onClick={this.props.showMessage} /> </div> ); }
关键修改说明
contains()方法的使用:!this.DOMArrowBox.current.contains(e.target)表示当点击的元素不在模态框容器及其子元素范围内时,才执行关闭逻辑。- 增加ref存在性检查:
this.DOMArrowBox.current && ...可以避免组件初始化阶段ref还未绑定导致的报错。 - 替换生命周期钩子:
componentDidMount在组件渲染完成后执行,此时ref已经正确关联到DOM元素,确保事件监听生效时ref可用。
这样修改后,点击模态框内部的任何元素都不会触发关闭,只有点击外部区域才会关闭弹窗啦~
内容的提问来源于stack exchange,提问作者Yerlan Yeszhanov
相关产品推荐
相关产品推荐

