webcomponents - hide dropdown menu on [removed]

后端 未结 2 1036
长发绾君心
长发绾君心 2021-01-27 10:48

dropdown menu is created in shadowDOM

almost perfect, but the problem is how to hide the dropdown menu when click on any where else in window

class NavC         


        
2条回答
  •  旧巷少年郎
    2021-01-27 11:03

    The best solution, as @guitarino suggested is to define a dropdown menu custom element.

    When the menu is clicked, call a (first) event handler that will show/hide the menu, and also add/remove a (second) dropdown event handler on window.

    At its turn, the (second) dropdown event handler will call the first event handler only if the action is outside the custom element itself.

    connectedCallback()
    {        
        //mousedown anywhere
        this.mouse_down = ev => !this.contains( ev.target ) && toggle_menu()
    
        //toggle menu and window listener 
        var toggle_menu = () => 
        {
            if ( this.classList.toggle( 'show' ) )
                window.addEventListener( 'mousedown', this.mouse_down )
            else
                window.removeEventListener( 'mousedown', this.mouse_down )
        }
    
        //click on menu
        this.addEventListener( 'click', toggle_menu )   
    }
    

    It works with or without Shadow DOM:

    customElements.define( 'drop-menu', class extends HTMLElement 
    {
      constructor ()
      {
        super()
        this.attachShadow( { mode: 'open'} )
            .innerHTML = ''
      }
    
      connectedCallback()
      {        
        //mousedown anywhere
        this.mouse_down = ev => !this.contains( ev.target ) && toggle_menu()
            
        //toggle menu and window listener 
        var toggle_menu = () => 
        {
          if ( this.classList.toggle( 'show' ) )
            window.addEventListener( 'mousedown', this.mouse_down )
          else
            window.removeEventListener( 'mousedown', this.mouse_down )
        }
    
        //click on menu
        this.addEventListener( 'click', toggle_menu )   
      }
    
      disconnectedCallback ()
      {
        this.removeEventListener( 'mousedown', this.mouse_down )
      }
    } )
    drop-menu  {
        position: relative ;
        cursor: pointer ;
        display: inline-block ;
    }
    
    drop-menu > output {
        border: 1px solid #ccc ;
        padding: 2px 5px ;
    }
    
    drop-menu > ul {
        box-sizing: content-box ;
        position: absolute ;
        top: 2px ; left: 5px ;
        width: 200px;
        list-style: none ;
        border: 1px solid #ccc ;
        padding: 0 ;
        opacity: 0 ;
        transition: all 0.2s ease-in-out ;
        background: white ;
        visibility: hidden ;
        z-index: 2 ;
    
    }
    
    drop-menu.show  > ul {
        opacity: 1 ;
        visibility: visible ;
    }
    
    drop-menu > ul > li {
        overflow: hidden ;
        transition: font 0.2s ease-in-out ;
        padding: 2px 5px ;
        background-color: #e7e7e7;
    }
    
    drop-menu:hover {
        cursor: pointer;
        background-color: #f2f2f2;
    }
    
    drop-menu  ul li:hover {
        background-color: #e0e0e0;
    }
    
    drop-menu ul li span {
        float: right;
        color: #f9f9f9;
        background-color: #f03861;
        padding: 2px 5px;
        border-radius: 3px;
        text-align: center;
        font-size: .8rem;
    }
    
    drop-menu ul li:hover span {
        background-color: #ee204e;
    }
    Services
      
    • Graphic desing
    • web design
    • app design
    • theme
    tutorial
    • css 12 available
    • php 10 available
    • javascript 40 available
    • html 20 available

提交回复
热议问题