【问题标题】:Handle outside click closes on clicking the modal itself. Basically shouldn't close when clicked anywhere but outside of the modal单击模态本身时处理外部单击关闭。在模式之外的任何地方单击时基本上不应该关闭
【发布时间】:2019-07-15 04:57:34
【问题描述】:

这段代码以前对我有用,但我不确定我尝试使用它的其他组件发生了什么变化。

我尝试使用钩子打开和关闭模式,并且只是简单地点击事件侦听器,但两次点击页面上的任何位置都会关闭。

componentDidMount() {
    document.addEventListener('click', this.handleOutsideClick);
  }

  componentWillUnmount() {
    document.removeEventListener('click', this.handleOutsideClick);
  }

  handleOutsideClick = (e) => {
    if (this.state.showInfoModal && !this.node.contains(e.target)) this.handleInfoToggle();
    console.log(this.state.showInfoModal, e.target, this.node, 'clicked outside');
  }

  handleInfoToggle = (event) => {
    const { showInfoModal } = this.state;

    if (event) event.preventDefault();
    this.setState({ showInfoModal: !showInfoModal });
  };

renderSomething = (args) => {
 return(
   <span ref={(node) => { this.node = node; }}>
   {something === true && <span className={styles.somethingelse}> 
   <HintIcon onClick={this.handleInfoToggle} /></span>}
    <Modal visible={showInfoModal} onCancel={this.handleInfoToggle}>
     some information to show
    </Modal>
   </span>
  )
}

render() => {
  return (
   {this.renderSomething(args)}
  )
}

不确定这是否足够信息。但这让我发疯。

我还尝试添加有人建议的 dontCloseModal 函数:

  dontCloseModal = (e) => {
    e.stopPropagation();
    console.log(e);
    this.setState({
      showInfoModal: true
    });
  }

 <div onClick={this.dontCloseModal}></div>

(((这将绕过&lt;Modal/&gt;组件)))

  const refs = React.createRef(); // Setup to wrap one child
  const handleClick = (event) => {
    const isOutside = () => {
      return !refs.current.contains(event.target);
    };
    if (isOutside) {
      onClick();
    }
  };

  useEffect(() => {
    document.addEventListener('click', handleClick);

    return function() {
      document.removeEventListener('click', handleClick);
    };
  });

  return (element, idx) => React.cloneElement(element, { ref: refs[idx] });
}

export default ClickOutside;

尝试使用这样的组件 ^^ 并添加 &lt;ClickOutside onClick={this.closeInfoModal()}&gt;&lt;/ClickOutside&gt; 但是同样的问题也会在点击任何地方(包括模态内部)时关闭

【问题讨论】:

  • 你是从哪个库导入 Modal 的?
  • 我使用了react-modal,但这是在另一个名为 的模态中使用的父模态,这是我用于模态的。我希望我说得通。问题是,它在应用程序的另一个模式中完美地工作,但这里有些不同,它在点击页面上的任意位置时关闭模式。
  • 您是否考虑将shouldCloseOnOverlayClick={false} 添加到模态框,例如&lt;Modal shouldCloseOnOverlayClick={false} /&gt; 这可以防止从模态组件外部关闭模态框
  • 嗨@trailblazer - 看看这个答案stackoverflow.com/a/54633645/4490712
  • @jank 谢谢!这确实解决了我的问题,但现在我无法在单击模式中的x 按钮时关闭模式:(

标签: reactjs modal-dialog


【解决方案1】:

玩了一会儿,看来你也应该在这里useRef。 如果用户在模态目标的外部和内部单击,这将允许您控制切换模态。

有很多复杂的方法可以实现这一点。但是,由于我们在这里处理的是钩子,所以最好使用自定义钩子。

介绍useOnClick?:

// Custom hook for controling user clicks inside & outside
function useOnClick(ref, handler) {
    useEffect(() => {
        const listener = event => {
            // Inner Click: Do nothing if clicking ref's element or descendent elements, similar to the solution I gave in my comment stackoverflow.com/a/54633645/4490712 
            if (!ref.current || ref.current.contains(event.target)) {
                return;
            }
            // Outer Click: Do nothing if clicking wrapper ref
            if (this.wrapperRef && !this.wrapperRef.contains(event.target)) {
                return;
            }

            handler(event);
        };

        // Here we are subscribing our listener to the document
        document.addEventListener("mousedown", listener);

        return () => {
            // And unsubscribing it when we are no longer showing this component
            document.removeEventListener("mousedown", listener);
        };
    }, []); // Empty array ensures that effect is only run on mount and unmount
}

观看此Demo in CodeSandBox,以便了解如何使用钩子实现。

欢迎来到 StackOverflow!

【讨论】:

  • 感谢您在每次操作后花时间解释!我对编程还很陌生,理解有时可能具有挑战性。使用您提供的解决方案,在模态之外单击时我无法关闭。我必须承认我还没有在我的应用程序中重构它,但是从沙箱中它不起作用。
  • @trailblazer - 这样做非常简单。这个钩子有两个条件。如果你去掉第二个 'if 语句(控制外部点击),那么你将允许用户在其区域外点击时关闭模式。
  • 我已经更新了我的演示,所以它会符合你的描述@trailblazer
  • 谢谢!!原来,模态组件是问题所在。因此,我没有使用自定义模式,而是直接使用 react-modal 并将其与您的解决方案相结合,解决了我的问题!
  • 我又遇到了这个问题:\ 这次是更大尺寸的模态,所以当我点击模态内容的左侧时,它会关闭。我像这样使用了 clientWidth if (isModalOpen &amp;&amp; e.clientX &lt;= e.target.offsetWidth) this.handleModalToggle(); 模态是 2 个组件深,我在页面中有多个模态。有什么想法我能做什么?我知道这个问题(它的 e.target.offsetWidth)没有覆盖整个模态!
猜你喜欢
  • 2019-07-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-06
  • 1970-01-01
相关资源
最近更新 更多