How to implement a Navbar Dropdown Hover in Bootstrap v4?

前端 未结 20 942
猫巷女王i
猫巷女王i 2020-12-02 05:40

I am a bit confused on the new bootstrap version since they changed dropdown menus to divs:

20条回答
  •  不思量自难忘°
    2020-12-02 06:16

    Simple, CSS only solution:

    .dropdown:hover>.dropdown-menu {
      display: block;
    }
    

    When clicked, it will still get the class show toggled to it (and will remain open when no longer hovered).


    To get around this properly is to use events and properties reserved to pointer based devices: jQuery's mouseenter, mouseleave and :hover. Should work smoothly, intuitively, while not interfering at all with how the dropdown works on touch based devices. Try it out, let me know if it works for you:

    Complete jQuery solution (touch untouched):

    Pre v4.1.2 solution (deprecated):

    $('body').on('mouseenter mouseleave','.dropdown',function(e){
      var _d=$(e.target).closest('.dropdown');
      if (e.type === 'mouseenter')_d.addClass('show');
      setTimeout(function(){
        _d.toggleClass('show', _d.is(':hover'));
        $('[data-toggle="dropdown"]', _d).attr('aria-expanded',_d.is(':hover'));
      },300);
    });
    

    $('body').on('mouseenter mouseleave','.dropdown',function(e){
      var _d=$(e.target).closest('.dropdown');
      if (e.type === 'mouseenter')_d.addClass('show');
      setTimeout(function(){
        _d.toggleClass('show', _d.is(':hover'));
        $('[data-toggle="dropdown"]', _d).attr('aria-expanded',_d.is(':hover'));
      },300);
    });
    
    /* this is not needed, just prevents page reload when a dd link is clicked */
    $('.dropdown a').on('click tap', e => e.preventDefault())
    
    
    
    
    
    


    v4.1.2 shiplist introduced this change to how dropdowns work, making the solution above no longer work.
    Here's the up to date solution for having the dropdown open on hover in v4.1.2 and above:

    function toggleDropdown (e) {
      const _d = $(e.target).closest('.dropdown'),
        _m = $('.dropdown-menu', _d);
      setTimeout(function(){
        const shouldOpen = e.type !== 'click' && _d.is(':hover');
        _m.toggleClass('show', shouldOpen);
        _d.toggleClass('show', shouldOpen);
        $('[data-toggle="dropdown"]', _d).attr('aria-expanded', shouldOpen);
      }, e.type === 'mouseleave' ? 300 : 0);
    }
    
    $('body')
      .on('mouseenter mouseleave','.dropdown',toggleDropdown)
      .on('click', '.dropdown-menu a', toggleDropdown);
    

    function toggleDropdown (e) {
      const _d = $(e.target).closest('.dropdown'),
          _m = $('.dropdown-menu', _d);
      setTimeout(function(){
        const shouldOpen = e.type !== 'click' && _d.is(':hover');
        _m.toggleClass('show', shouldOpen);
        _d.toggleClass('show', shouldOpen);
        $('[data-toggle="dropdown"]', _d).attr('aria-expanded', shouldOpen);
      }, e.type === 'mouseleave' ? 300 : 0);
    }
    
    $('body')
      .on('mouseenter mouseleave','.dropdown',toggleDropdown)
      .on('click', '.dropdown-menu a', toggleDropdown);
    
    /* not needed, prevents page reload for SO example on menu link clicked */
    $('.dropdown a').on('click tap', e => e.preventDefault())
    
    
    
    
    
    


    Important note: If using the jQuery solution, it is important to remove the CSS one (or the dropdown won't close when .dropdown-toggle is clicked or when an menu option is clicked).

提交回复
热议问题