How to implement a Navbar Dropdown Hover in Bootstrap v4?

前端 未结 20 874
猫巷女王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:33

    I use bootstrap 4.0.0 since we want to simulate .show to hover event, it simply easy. just add all styles in .dropdown.show .dropdown-menu to the :hover. like this:

    .dropdown:hover>.dropdown-menu {
      opacity: 1;
      visibility: visible;
      transform: translate3d(0px, 0px, 0px);
    }
    
    0 讨论(0)
  • 2020-12-02 06:33

    I couldn't find here the full solution. So, it's my one which works with Bootstrap v4.4.1 and has the next benefits:

    • A click on the dropdown-toggle works as a normal nav link.

    • Supports any nesting level of dropdown menus.

    • Bootstrap 4 {show/shown/hide/hidden}.bs.dropdown events work well.

       // Toggles a B4 dropdown-menu to a given state.
       const toggleDropdownElement = ($dropdown, shouldOpen = false) => {
         const $dropdownToggle = $dropdown.children('[data-toggle="dropdown"], a');
         const $dropdownMenu = $dropdown.children('.dropdown-menu');
      
         // Change the dropdown menu. It's similar to B4 Dropdown.show()/.hide(), see /bootstrap/js/src/dropdown.js.
         if (shouldOpen) {
           $dropdown.trigger('show.bs.dropdown');
           $dropdownToggle.attr('aria-expanded', true).focus();
           $dropdownMenu.addClass('show');
           $dropdown.addClass('show').trigger($.Event('shown.bs.dropdown', $dropdownMenu[0]));
         } else {
           $dropdown.trigger('hide.bs.dropdown');
           $dropdownToggle.attr('aria-expanded', false);
           $dropdownMenu.removeClass('show');
           $dropdown.removeClass('show').trigger($.Event('hidden.bs.dropdown', $dropdownMenu[0]));
         }
       };
      
       // Toggles a B4 dropdown-menu with any nesting level.
       const toggleDropdown = (event) => {
         const $dropdown = $(event.target).closest('.dropdown');
         const $parentDropdownMenu = $dropdown.closest('.dropdown-menu');
         const shouldOpen = event.type !== 'click' && $dropdown.is(':hover');
      
         // If the dropdown was closed already, break the 'mouseleave' event cascade.
         if (!shouldOpen && !$dropdown.hasClass('show')) return;
      
         // Change the current dropdown menu (last nested).
         toggleDropdownElement($dropdown, shouldOpen);
      
         // We have to close the dropdown menu tree if it was a click or the menu was leave at all.
         if (event.type === 'click' || $parentDropdownMenu.length && !$parentDropdownMenu.is(':hover')) {
           $dropdown.parents('.dropdown').each((index, element) => {
             toggleDropdownElement($(element), false);
           });
         }
       };
      
       if (viewport && viewport.is('>=xl')) {
         $('body')
           .on('mouseenter mouseleave', '.dropdown', toggleDropdown)
           .on('click', '.dropdown-menu a', toggleDropdown);
      
         // Disable the default B4's click. Other words, change a dropdown-toggle to a normal nav link.
         $(document).off('click.bs.dropdown', '[data-toggle="dropdown"]');
         $(document).off('click.bs.dropdown.data-api', '[data-toggle="dropdown"]'); // Not sure about it.
       }
      

    If you don't use ES6 just change arrow functions to the old function style.

    Thanks, @tao for your example, it was helpful for me.

    Code related links: B4 Dropdown Events, viewport (Responsive Bootstrap Toolkit), WP Bootstrap Navwalker.

    0 讨论(0)
  • 2020-12-02 06:33

    <div style="width: 100%; overflow: scroll;"><table class="table table-striped table-bordered" style="font-size:12px">

    0 讨论(0)
  • 2020-12-02 06:37

    This solution switches on and off

    <script>
    $(document).ready(function() {
      // close all dropdowns that are open
      $('body').click(function(e) {
          $('.nav-item.show').removeClass('show');
          //$('.nav-item.clicked').removeClass('clicked');
          $('.dropdown-menu.show').removeClass('show');
      });
    
      $('.nav-item').click( function(e) {
        $(this).addClass('clicked')
      });
    
      // show dropdown for the link clicked
      $('.nav-item').hover(function(e) {
          if ($('.nav-item.show').length < 1) {
            $('.nav-item.clicked').removeClass('clicked');
          }
          if ($('.nav-item.clicked').length < 1) {
              $('.nav-item.show').removeClass('show');
              $('.dropdown-menu.show').removeClass('show');
              $dd = $(this).find('.dropdown-menu');
              $dd.parent().addClass('show');
              $dd.addClass('show');
          }
      });
    });</script>
    

    To disable the hover for lg sized collapse menus add

    if(( $(window).width() >= 992 )) {
    
    0 讨论(0)
  • 2020-12-02 06:39

    Hoverable dropdown without losing functionality of popper.js for bootstrap 4 only

    Javascript

    $('.dropdown-hoverable').hover(function(){
        $(this).children('[data-toggle="dropdown"]').click();
    }, function(){
        $(this).children('[data-toggle="dropdown"]').click();
    });
    

    HTML

    <nav class="nav">
      <li class="nav-item dropdown dropdown-hoverable">
        <a class="nav-link dropdown-toggle" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" href="#">Menu link</a>
        <ul class="dropdown-menu">
        </ul>
      </li>
    </nav>
    
    0 讨论(0)
  • 2020-12-02 06:42

    Andrei's "complete" jQuery+CSS solution has the right intent, but it's verbose and still incomplete. Incomplete because while it probably covers all the necessary DOM changes, it's missing the firing of custom events. Verbose because it's wheel-reinventing when Bootstrap already provides the dropdown() method, which does everything.

    So the correct, DRY solution, which does not rely on the CSS hack often repeated among other answers, is just jQuery:

    $('body').on('mouseover mouseout', '.dropdown', function(e) {
        $(e.target).dropdown('toggle');
    });
    
    0 讨论(0)
提交回复
热议问题