jquery 如何隐藏菜单时,你点击它以外的React?[副本]

vh0rcniy  于 2023-08-04  发布在  jQuery
关注(0)|答案(1)|浏览(94)

此问题在此处已有答案

React closing a dropdown when click outside(5个答案)
20天前关闭。
我用React和Tailwind构建了一个CRUD Web App。我创建了一个导航栏与下拉菜单时,应用程序显示在移动的上。
当你点击按钮时,我会显示菜单,但我不知道如何隐藏菜单,当你用React在菜单外点击时。


的数据

import React, { Component, useState } from 'react'
import { Link } from 'react-router-dom'

const NavBar = () => {

    const [isOpen, setIsOpen] = useState(false);

    const displayResponsiveMenu = () => {
        setIsOpen(!isOpen)
    }

    return (
        <nav>
            <div className="flex items-center justify-between flex-wrap bg-teal-500 p-6">

                ...

                <div className="block lg:hidden">
                    <button onClick={displayResponsiveMenu} className="flex items-center px-3 py-2 border rounded text-teal-200 border-teal-400 hover:text-white hover:border-white">
                        {
                            !isOpen ?
                                <svg className="fill-current h-3 w-3" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><title>Menu</title><path d="M0 3h20v2H0V3zm0 6h20v2H0V9zm0 6h20v2H0v-2z" /></svg>
                                :
                                <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 20 20" strokeWidth="1.5" stroke="currentColor" className="w-3 h-3">
                                    <path strokeLinecap="round" strokeLinejoin="round" d="M6 18L18 6M6 6l12 12" />
                                </svg>
                        }
                    </button>
                </div>

                ...

            </div>
            {
                isOpen ?
                    <div className="flex items-center justify-between flex-wrap bg-teal-500 pl-6 pt-2 pb-2">
                        <ul>
                            <li>
                                <Link to="/users" className="block lg:mt-0 text-teal-200 hover:text-white mr-4">
                                    Users
                                </Link>
                            </li>
                        </ul>
                    </div> : null
            }
        </nav>
    )
}

export default NavBar

字符串

wz8daaqr

wz8daaqr1#

试试这个代码

编辑:

import React, { useState, useEffect, useRef } from 'react';
import { Link } from 'react-router-dom';

const NavBar = () => {
  const [isOpen, setIsOpen] = useState(false);
  const menuRef = useRef(null);
  const buttonRef = useRef(null);

  const displayResponsiveMenu = () => {
    setIsOpen(!isOpen);
  };

  const handleOutsideClick = (event) => {
    if (
      menuRef.current &&
      !menuRef.current.contains(event.target) &&
      event.target !== buttonRef.current
    ) {
      setIsOpen(false);
    }
  };

  useEffect(() => {
    document.addEventListener('mousedown', handleOutsideClick);
    return () => {
      document.removeEventListener('mousedown', handleOutsideClick);
    };
  }, []);

  return (
    <nav>
      <div className="flex items-center justify-between flex-wrap bg-teal-500 p-6">
        <div className="flex items-center flex-shrink-0 text-white mr-6">
          <svg
            xmlns="http://www.w3.org/2000/svg"
            fill="none"
            viewBox="0 0 24 24"
            strokeWidth="1.5"
            stroke="currentColor"
            className="w-6 h-6"
          >
            <path
              strokeLinecap="round"
              strokeLinejoin="round"
              d="M15.75 6a3.75 3.75 0 11-7.5 0 3.75 3.75 0 017.5 0zM4.501 20.118a7.5 7.5 0 0114.998 0A17.933 17.933 0 0112 21.75c-2.676 0-5.216-.584-7.499-1.632z"
            />
          </svg>
          <span className="font-semibold text-xl tracking-tight ml-2">
            Random User App
          </span>
        </div>
        <div className="block lg:hidden">
          <button
            ref={buttonRef}
            onClick={displayResponsiveMenu}
            className="flex items-center px-3 py-2 border rounded text-teal-200 border-teal-400 hover:text-white hover:border-white"
          >
            {isOpen ? (
              <svg
                xmlns="http://www.w3.org/2000/svg"
                fill="none"
                viewBox="0 0 20 20"
                strokeWidth="1.5"
                stroke="currentColor"
                className="w-3 h-3"
              >
                <path
                  strokeLinecap="round"
                  strokeLinejoin="round"
                  d="M6 18L18 6M6 6l12 12"
                />
              </svg>
            ) : (
              <svg
                className="fill-current h-3 w-3"
                viewBox="0 0 20 20"
                xmlns="http://www.w3.org/2000/svg"
              >
                <title>Menu</title>
                <path d="M0 3h20v2H0V3zm0 6h20v2H0V9zm0 6h20v2H0v-2z" />
              </svg>
            )}
          </button>
        </div>
        <div
          className="w-full lg:block flex-grow lg:flex lg:items-center lg:w-auto hidden"
          ref={menuRef}
        >
          <div className="text-lg lg:flex-grow">
            <Link
              to="/users"
              className="block mt-4 lg:mt-0 text-teal-200 hover:text-white mr-4"
            >
              Users
            </Link>
          </div>
        </div>
      </div>
      {isOpen ? (
        <div className="flex items-center justify-between flex-wrap bg-teal-500 pl-6 pt-2 pb-2">
          <ul>
            <li>
              <Link
                to="/users"
                className="block lg:mt-0 text-teal-200 hover:text-white mr-4"
              >
                Users
              </Link>
            </li>
          </ul>
        </div>
      ) : null}
    </nav>
  );
};

export default NavBar;

字符串

说明:

1.创建一个新的引用buttonRef来引用菜单按钮元素。
第一个月
此引用将用于存储对菜单按钮元素的引用。我们将使用ref属性将此引用附加到JSX代码中的菜单按钮元素。
1.handleOutsideClick函数中,添加一个附加条件,检查单击的目标(event.target)是否与菜单按钮(buttonRef.current)的引用匹配。如果单击目标是菜单按钮,则不应关闭菜单。

const handleOutsideClick = (event) => {
 if (
   menuRef.current &&
   !menuRef.current.contains(event.target) &&
   event.target !== buttonRef.current
 ) {
   setIsOpen(false);
 }
};


在这一步中,我们修改handleOutsideClick函数以包含一个额外的检查:event.target !== buttonRef.current。此条件检查单击的目标是否与菜单按钮(buttonRef.current)不同。如果点击目标是菜单按钮,我们知道用户点击了菜单按钮本身,在这种情况下,我们不想关闭菜单。这可以防止菜单在打开后立即关闭。

4:useEffect钩子用于为文档上的mousedown事件添加事件监听器,当发生mousedown事件时调用handleOutsideClick函数。

useEffect(() => {
  document.addEventListener('mousedown', handleOutsideClick);
  return () => {
    document.removeEventListener('mousedown', handleOutsideClick);
  };
}, []);


在这一步中,我们使用useEffect钩子为整个文档上的mousedown事件添加一个事件侦听器。我们通过调用document.addEventListener('mousedown', handleOutsideClick)来实现这一点。这允许我们检测页面上任何地方的点击。我们使用useEffect钩子的cleanup函数在卸载组件时删除事件侦听器。这可以确保我们清理任何以前添加的事件侦听器,以避免潜在的内存泄漏。
希望对你有帮助。如果可行的话,请接受这个答案。

相关问题