最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Open and Close Dropdown menu on by mouse hover in react js - Stack Overflow

programmeradmin2浏览0评论

I am new to React JS. My problem is that I want the menu to disappear if the mouse leaves that area, so I tried onMouseOut and onMouseLeave to close the menu but it seems that when this option is there the menu never opens! But when I remove the onMouseOver or Leave then it works fine but just stays there if you don't click something. MenuListProps={{ onMouseLeave: handleClose }}

That happens because when I open the menu, a modal layout is placed over the whole page, which means the onMouseLeave event will be fired immediately after onMouseEnter. but for it to work I must change the menu anchor so that it covers the button in its entirety

<div>
            {menuItem.map((text) => (
              <Button               
                onClick={(e) => handleChangeMenu(text, e)}
                onMouseOver={(e) => handleHover(text, e)}>
                {text}            
              </Button>
            ))}
            <Menu
              transitionDuration={700}
              anchorEl={project}
              open={Boolean(project)}
              onClose={() => {
                setproject(null);
              }}
              MenuListProps={{
                onMouseLeave: () => {
                  setproject(null);
                },
              }}
            >
              {mySubMenu.map((text) => (
                <MenuItem sx={menuItemStyle}>{text}</MenuItem>
              ))}
            </Menu>
          </div>

I am new to React JS. My problem is that I want the menu to disappear if the mouse leaves that area, so I tried onMouseOut and onMouseLeave to close the menu but it seems that when this option is there the menu never opens! But when I remove the onMouseOver or Leave then it works fine but just stays there if you don't click something. MenuListProps={{ onMouseLeave: handleClose }}

That happens because when I open the menu, a modal layout is placed over the whole page, which means the onMouseLeave event will be fired immediately after onMouseEnter. but for it to work I must change the menu anchor so that it covers the button in its entirety

<div>
            {menuItem.map((text) => (
              <Button               
                onClick={(e) => handleChangeMenu(text, e)}
                onMouseOver={(e) => handleHover(text, e)}>
                {text}            
              </Button>
            ))}
            <Menu
              transitionDuration={700}
              anchorEl={project}
              open={Boolean(project)}
              onClose={() => {
                setproject(null);
              }}
              MenuListProps={{
                onMouseLeave: () => {
                  setproject(null);
                },
              }}
            >
              {mySubMenu.map((text) => (
                <MenuItem sx={menuItemStyle}>{text}</MenuItem>
              ))}
            </Menu>
          </div>

Share Improve this question edited Nov 29, 2022 at 11:29 Manoj Kumar Joshi 11610 bronze badges asked Mar 29, 2022 at 7:13 Durai DDDurai DD 3071 gold badge3 silver badges11 bronze badges 5
  • Consider using CSS instead of JS for hover interactions – evolutionxbox Commented Mar 29, 2022 at 7:27
  • Is there any possibilities in reactjs ? and could you share me the example ? @evolutionxbox – Durai DD Commented Mar 29, 2022 at 7:32
  • .myElement:hover .child { display: block; } – evolutionxbox Commented Mar 29, 2022 at 7:33
  • this medium article helped me with a nextui dropdown issue, maybe it can point you in the right direction. medium./@rwchampin/… – Ryan Commented Nov 30, 2023 at 22:04
  • For a library that implement this. Quote: > Alternative I found : <jcoreio.github.io/material-ui-popup-state> here (#9893) – Nor.Z Commented Feb 12 at 12:05
Add a ment  | 

4 Answers 4

Reset to default 0

There is exists specified material ponent ClickAwayListener.

You can add mouse leave event handler like this

 <ClickAwayListener mouseEvent="onMouseDown" onClickAway={handleDropdownClickAway}>{your menu code}</ClickAwayListener>

For this kind of situations i am using onBlur, had same issue, add onBlur event to your Menu ponent

onBlur={() => {
   setproject(null);
}}

Ussually i have in state a constant that holds the value to show dropdown or not, below is how i do in my projects

const [showOptions, setShowOptions] = React.useState<boolean>(false)
const showOption = (): void => {
    setShowOptions(!showOptions)
}

const onBlur = (): void => {
    setShowOptions(false)
}

const onMouseDown = (): void => {
    setShowOptions(false)
}

// here adding all events to your menu
// if u decide to use a constant to tell u to show dropdown, than pass showOptions as a prop inside YourMenu poennt and hide show your dropdown using showOptions constant
<YourMenu                    
    onClick={showOption}
    onKeyDown={showOption}
    onBlur={onBlur}
    showOptions={showOptions} // prop to show hide your dropdown
 >

You can add div as a container of Button and Menu, and add att. onMouseLeave to it.

<div>
    {menuItem.map((text) => (
       <div key={text}
            style={{ display: 'inline-block' }}
            onMouseLeave={() => setproject(null)}    // <== Here
       >
            <Button               
                onClick={(e) => handleChangeMenu(text, e)}
                onMouseOver={(e) => handleHover(text, e)}
                id={text}                            // <== Here
            >
                {text}            
             </Button>
             <Menu
                 transitionDuration={700}
                 anchorEl={project}
                 open={Boolean(anchorElBtn) && anchorElBtn.id === text}     // <== Here
                 onClose={() => {
                   setproject(null);
                 }}
            >
              {mySubMenu.map((text) => (
                <MenuItem sx={menuItemStyle}>{text}</MenuItem>
              ))}
            </Menu>
       </div>
   ))}
</div>

It seems that the event that hide the menu

onMouseLeave: () => {
   setproject(null);
},

only happens on <Menu element

a possible solution is here

  1. add the same event to <Button element so that it hides the menu when mouse leaves its area
  • I assume <Button is from an external ui library. You may need to check properties to make sure onMouseLeave works
<div>
  {menuItem.map((text) => (
    <Button               
      onClick={(e) => handleChangeMenu(text, e)}
      onMouseOver={(e) => handleHover(text, e)}>
      {text}
      onMouseLeave={() => setproject(null)}        
    </Button>
  ))}
  <Menu
    transitionDuration={700}
    anchorEl={project}
    open={Boolean(project)}
    onClose={() => {
      setproject(null);
    }}
    MenuListProps={{
      onMouseLeave: () => {
        setproject(null);
      },
    }}
  >
    {mySubMenu.map((text) => (
      <MenuItem sx={menuItemStyle}>{text}</MenuItem>
    ))}
  </Menu>
</div>
发布评论

评论列表(0)

  1. 暂无评论