单击外部组件时关闭弹出窗口

Posted

技术标签:

【中文标题】单击外部组件时关闭弹出窗口【英文标题】:Closing popup on clicking outside component 【发布时间】:2019-11-10 06:53:57 【问题描述】:

在写这篇文章之前,我看到了this post,但我无法将所有代码链接到我的。

这是我的切换组件:

<ToggleContent
          toggle=show => (
            <div>
              <button type="button" onClick=show className=styles.acronym>
                acronym
              </button>
            </div>
          )
          
          content=show => (
            <LogoutCard onClick=show acronym=acronym name=name />
          )
        />

这是ToggleContent的内部

function ToggleContent( toggle, content ) 
  const [isShown, setIsShown] = useState(false);
  const hide = () => setIsShown(false);
  const show = () => setIsShown(!isShown);

  return (
    <Fragment>
      toggle(show)
      isShown && content(hide)
    </Fragment>
  );

这是 LogoutCard 在 props content 中的包装

import React,  useRef, useEffect  from "react";

/**
 * Hook that alerts clicks outside of the passed ref
 */
function useOutsideAlerter(ref) 
  /**
   * Alert if clicked on outside of element
   */
  function handleClickOutside(event) 
    if (ref.current && !ref.current.contains(event.target)) 
      alert("You clicked outside of me!");
    
  

  useEffect(() => 
    // Bind the event listener
    document.addEventListener("mousedown", handleClickOutside);
    return () => 
      // Unbind the event listener on clean up
      document.removeEventListener("mousedown", handleClickOutside);
    ;
  );


/**
 * Component that alerts if you click outside of it
 */
export default function OutsideAlerter(props) 
  const wrapperRef = useRef(null);
  useOutsideAlerter(wrapperRef);

  return <div ref=wrapperRef>props.children</div>;

问题

问题是我可以打印警报,但我无法关闭弹出窗口,因为我无法传递 show 值,这是唯一允许关闭和打开的小弹出窗口。

问题

如何关闭弹出窗口?

【问题讨论】:

如果你能把它放在 jsFiddle 或 codeSandbox 之类的东西里会很好。 【参考方案1】:

您需要传递一个名称 onClick 函数来处理执行所需的逻辑以根据需要关闭弹出窗口。此外,将逻辑简化为仅否定当前状态的 toggle 操作就足以管理弹出窗口的显示/隐藏行为。

import React,  useRef, useEffect  from "react";

/**
 * Hook that alerts clicks outside of the passed ref
 */
function useOutsideAlerter(ref, onClick) 
  /**
   * Alert if clicked on outside of element
   */
  function handleClickOutside(event) 
    if (ref.current && !ref.current.contains(event.target)) 
      alert("You clicked outside of me!");
      onClick();
    
  

  useEffect(() => 
    // Bind the event listener
    document.addEventListener("mousedown", handleClickOutside);
    return () => 
      // Unbind the event listener on clean up
      document.removeEventListener("mousedown", handleClickOutside);
    ;
  , [handleClickOutside]);


/**
 * Component that alerts if you click outside of it
 */
export default function OutsideAlerter(props) 
  const wrapperRef = useRef(null);

  return <div ref=wrapperRef>props.children</div>;


function ToggleContent( toggle, content ) 
  const [isShown, setIsShown] = useState(false);

  const toggle = () => setIsShown(!isShown);

  const onClick = () => 
    toggle()
  
  useOutsideAlerter(wrapperRef, onClick);

  return (
    <Fragment>
      toggle(show)
      isShown && content()
    </Fragment>
  );

【讨论】:

只是一个听起来很愚蠢的问题,但考虑到这是我作为 Web 开发人员的第二个月:我可以使用函数 `useOutsideAlerter(wrapperRef, onClick); ` 通过只导入组件 OutsideAlerter(logoutCard 的包装器)? 没有。此外,您应该将其导入应该执行的位置。在您的情况下,适合的地方是 ToggleContent 组件。 OutsideAlerter 是您通过 content 属性在 ToggleContent 中渲染的函数。

以上是关于单击外部组件时关闭弹出窗口的主要内容,如果未能解决你的问题,请参考以下文章

单击外部时隐藏Angular UI Bootstrap弹出窗口

尝试通过单击打开它的 div 中断按钮外部来关闭弹出窗口

如何通过单击外部来关闭 Twitter Bootstrap 弹出窗口?

关闭表单提交时打开的弹出窗口并触发单击父窗口

如果关闭弹出窗口,QComboBox将保留鼠标悬停突出显示

在正文单击时关闭简单的 jQuery 弹出窗口