2017-12-28 15 views
1

Ich fing gerade an zu plattieren mit reagieren. Ich arbeite gerade an meiner navBar mit Material-Ui und reagiere. Wenn ich den Mauszeiger über das Menü bewege, wird das Drop-down-Menü angezeigt. Um das Drop-Down-Menü zu schließen, muss ich jedoch auf die Außenseite des Dropdown-Menüs klicken. Ich möchte das Dropdown-Menü schließen können, wenn ich die Dropdown-Liste verlassen oder zu der anderen Menüoption wechseln (in diesem Fall sollte ein anderes Dropdown-Menü angezeigt werden). Etwas wie dieses: https://www.palantir.com/Menü bei mouseover öffnen und Menü auf mouseleave in react schließen

Ich sah mich um, aber ich fand die Lösung nicht. Das war das nächste, das ich bekam: Material-ui: open menu by event hover

Ich versuchte mit der gleichen Technik und fügte dies zu meinem Code, aber ohne Erfolg. Irgendwelche Vorschläge? Vielen Dank!

Bearbeitungen: Ich habe mein Problem hier neu erstellt: https://react-xmaiyw.stackblitz.io Das Problem kann gesehen werden, wenn Sie auf "Warum uns" geklickt haben.

handleClick = (event) => { 
event.preventDefault(); 

    this.setState({ 
    open: true, 
    anchorEl: event.currentTarget, 
    }); 
}; 

handleRequestClose =() => { 
    this.setState({ 
    open: false, 
    }); 
}; 

render() { 
return (
    <FlatButton 
    onClick={this.handleClick} 
    onMouseOver={this.handleClick} 
    onMouseLeave={this.handleRequestClose} //When I add this line of 
    //code, it keeps flickering very fast almost as if drop-down 
    //doesn't open 
    label="Why Us?" 
/> 
)} 
+1

Ich weiß nicht, ob dies die Antwort ist, die Sie suchen, da Sie bereits eine Menge Javascript geschrieben haben, aber dies kann ganz einfach ohne Javascript mit dem CSS-Pseudoelement 'Hover' gemacht werden. W3Schools hat ein hervorragendes Tutorial, wie man das in einer Dropdown-Menü-Einstellung [hier] implementiert (https://www.w3schools.com/howto/howto_css_dropdown.asp "Dropdown-Menü") Wenn dies nicht der Effekt ist, den Sie gesucht haben Bitte fügen Sie Ihr Markup hinzu, damit wir besser sehen können, wofür Sie sich entscheiden. –

+0

Ich versuche, es mit js im Vergleich zu CSS arbeiten zu lassen. Ich habe meine ursprüngliche Frage bearbeitet und einen funktionierenden Link zu meinem Problem hinzugefügt. Vielen Dank :) – abidishajia

Antwort

0

Das Flackern wird durch das Öffnen des Menüs unter der Maus verursacht. Wenn sich das Menü öffnet, befindet sich die Maus nicht mehr über dem Button, so dass es ein mouseleave Event auslöst, das Menü schließt, so dass sich Ihre Maus nun über dem Button befindet, und ein mouseenter Event auslöst, welches das Menü öffnet ... und so weiter auf und so weiter.

Sie können erreichen, was Sie möchten, mit einer zusätzlichen Logik, um zu verfolgen, wo die Maus ist, und eine Zeitüberschreitung, um sicherzustellen, dass der Benutzer Zeit hat, die Maus zwischen der Schaltfläche und dem Menü zu wechseln.

import React from 'react'; 
import Button from 'material-ui/Button'; 
import Menu, { MenuItem } from 'material-ui/Menu'; 

const timeoutLength = 300; 

class SimpleMenu extends React.Component { 
    state = { 
    anchorEl: null, 

    // Keep track of whether the mouse is over the button or menu 
    mouseOverButton: false, 
    mouseOverMenu: false, 
    }; 

    handleClick = event => { 
    this.setState({ open: true, anchorEl: event.currentTarget }); 
    }; 

    handleClose =() => { 
    this.setState({ mouseOverButton: false, mouseOverMenu: false }); 
    }; 

    enterButton =() => { 
    this.setState({ mouseOverButton: true }); 
    } 

    leaveButton =() => { 
    // Set a timeout so that the menu doesn't close before the user has time to 
    // move their mouse over it 
    setTimeout(() => { 
     this.setState({ mouseOverButton: false }); 
    }, timeoutLength); 
    } 

    enterMenu =() => { 
    this.setState({ mouseOverMenu: true }); 
    } 

    leaveMenu =() => { 
    setTimeout(() => { 
     this.setState({ mouseOverMenu: false }); 
    }, timeoutLength); 
    } 

    render() { 
    // Calculate open state based on mouse location 
    const open = this.state.mouseOverButton || this.state.mouseOverMenu; 

    return (
     <div> 
     <Button 
      aria-owns={this.state.open ? 'simple-menu' : null} 
      aria-haspopup="true" 
      onClick={this.handleClick} 
      onMouseEnter={this.enterButton} 
      onMouseLeave={this.leaveButton} 
     > 
      Open Menu 
     </Button> 
     <Menu 
      id="simple-menu" 
      anchorEl={this.state.anchorEl} 
      open={open} 
      onClose={this.handleClose} 
      MenuListProps={{ 
      onMouseEnter: this.enterMenu, 
      onMouseLeave: this.leaveMenu, 
      }} 

     > 
      <MenuItem onClick={this.handleClose}>Profile</MenuItem> 
      <MenuItem onClick={this.handleClose}>My account</MenuItem> 
      <MenuItem onClick={this.handleClose}>Logout</MenuItem> 
     </Menu> 
     </div> 
    ); 
    } 
} 

export default SimpleMenu; 

I verwendet, um die MenuListProps die mouseEnter und mouseLeave Ereignisse auf der MenuList selbst direkt zu setzen, weil die Menu Komponente ein Bündel von unsichtbaren (disply: none) Übergangselemente enthält, die seltsame Wirkungen auf Mausereignisse haben. Das MenuList ist das Element, das tatsächlich angezeigt wird, so dass es sinnvoll ist, die Mausereignisse direkt darauf festzulegen.

Sie müssen wahrscheinlich mit dem timeoutLength und Übergängen herumspielen, um alles glatt aussehen zu lassen.

Verwandte Themen