【问题标题】:Outside click event listener isnt working: Reactjs外部点击事件监听器不工作:Reactjs
【发布时间】:2022-11-17 21:04:56
【问题描述】:

我正在实施一个从右侧打开的自定义侧面板。我可以通过单击按钮实现面板的显示和隐藏。但是当我点击外部时,我希望隐藏同样的东西。我附加了外部点击处理程序,当我这样做时它甚至没有出现。有人可以帮忙吗

https://codesandbox.io/s/react-sliding-pane-v2-4xuj57?file=/src/SlideDrawer.jsx:100-173

import React, { useRef, useCallback, useEffect } from "react";
import "./styles.css";

export default function SlideDrawer({ show, setDrawerOpen }) {
  const sideMenuRef = useRef(null);

  const onOutsideClick = useCallback(() => {
    setDrawerOpen(false);
  }, [setDrawerOpen]);

  useEffect(() => {
    document.addEventListener("click", onOutsideClick);
    return () => document.removeEventListener("click", onOutsideClick);
  }, [onOutsideClick]);

  return (
    <div ref={sideMenuRef} className={`panel ${show && "slidein"}`}>
      I am sliding
    </div>
  );
}

import React, { useState } from "react";
import ReactDOM from "react-dom";
import SlideDrawer from "./SlideDrawer.jsx";
import "./styles.css";

function App() {
  const [drawerOpen, setDrawerOpen] = useState(false);

  return (
    <div className="box">
      <SlideDrawer show={drawerOpen} setDrawerOpen={setDrawerOpen} />
      <button onClick={() => setDrawerOpen((prev) => !prev)}>Click me!</button>
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

【问题讨论】:

    标签: javascript html reactjs ecmascript-6 react-hooks


    【解决方案1】:

    怎么了:

    如果单击该按钮,drawerOpen 将设置为 true 并立即再次设置为 false。您可以通过添加来验证

      React.useEffect(() => {
        console.log(drawerOpen)
      }, [drawerOpen])
    

    到 index.js。

    要解决此问题,您需要检查点击是否针对您的 eventListener 中的按钮。

    您可以通过给按钮一个 id 来解决它:

          <button id="openPanelButton" onClick={() =>setDrawerOpen((prev) => !prev)}>Click me!</button>
    

    然后像这样检查点击:

    import React, { useRef, useCallback, useEffect } from "react";
    import "./styles.css";
    
    export default function SlideDrawer({ show, setDrawerOpen }) {
      const sideMenuRef = useRef(null);
    
      const handleClick = useCallback((event) => {
        if (event.target.id !== "openPanelButton" && event.target !== sideMenuRef.current) {
          setDrawerOpen(false);
        }
      }, [setDrawerOpen]);
    
      useEffect(() => {
        document.addEventListener("click", handleClick);
        return () => document.removeEventListener("click", handleClick);
      }, [handleClick]);
    
      return (
        <div ref={sideMenuRef} className={`panel ${show && "slidein"}`}>
          I am sliding
        </div>
      );
    }
    
    

    【讨论】:

    • 你能告诉我我们如何实现这一目标吗?
    • 我在上面编辑了我的答案以包含一个解决方案。
    • 仍然在外面点击面板没有被隐藏
    • 抱歉,没仔细看。我再次编辑了答案。
    【解决方案2】:

    要实现所需的行为,您需要将要查找的事件从“单击”更改为“鼠标按下”,如下所示:

    document.addEventListener("mousedown", onOutsideClick);
    

    这样,同一次点击就不会同时触发打开和关闭。

    同时更新打开抽屉的 onClick 并检查它是否已经打开。

    这样它会起作用

    【讨论】:

    猜你喜欢
    • 2014-07-12
    • 1970-01-01
    • 1970-01-01
    • 2021-04-13
    • 2016-07-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-27
    相关资源
    最近更新 更多