首页 > 解决方案 > 检测 div 外的点击并切换菜单

问题描述

我有一个切换菜单,我正在尝试检测菜单外的点击事件以便能够关闭菜单,当用户在菜单外单击时我可以关闭菜单,但是要再次打开菜单,您必须单击两次,有谁知道我必须做些什么来解决这个问题,(菜单应该一键打开)

const RightMenu = ({ t, history }) => {
  let [menuOpen, setMenuOpen] = useState(false);

  const menuDiv = useRef({});
  const toggleMenu = useRef();

  useEffect(() => {
    window.addEventListener("click", () => {
      if ((menuDiv.current.style.display = "block")) {
        menuDiv.current.style.display = "none";
      }
    });
    return () => {
      window.removeEventListener("click", () => {});
    };
  }, []);

  const handleClick = e => {
    e.stopPropagation();
    if (menuOpen === false) {
      menuDiv.current.style.display = "block";
      setMenuOpen(true);
    }
    if (menuOpen === true) {
      menuDiv.current.style.display = "none";
      setMenuOpen(false);
    }
  };

  return (
    <div>
      <div
        id="menu"
        ref={menuDiv}
        style={{
          display: "none"
        }}
      >Menu items</div>

      <div
        className="text-center"
        ref={toggleMenu}
        onClick={e => handleClick(e)}
      > Menu Button</div> 
    ) 
}

标签: javascriptreactjsecmascript-6

解决方案


当您的组件卸载时,您实际上并没有从窗口中删除事件侦听器。的第二个参数removeEventListener应该是对您添加的同一个函数的引用addRemoveListener。例如

  useEffect(() => {
    const closeMenu = () => {
      if ((menuDiv.current.style.display = "block")) {
        menuDiv.current.style.display = "none";
      }
    };
    window.addEventListener("click", closeMenu);
    return () => {
      window.removeEventListener("click", closeMenu);
    };
  }, []);

推荐阅读