【问题标题】:Bootstrap 3 Dropdowns: on Hover and on ClickBootstrap 3 下拉菜单:悬停和点击
【发布时间】:2014-09-01 07:51:48
【问题描述】:

我的导航栏上几乎所有的链接都是下拉菜单。我希望它们出现在大屏幕的悬停上,但在点击小屏幕时出现。那可能吗?在我寻找答案的过程中,我遇到了这个:Bootstrap Menu: Dropdown on Hover for Desktop Only。这对我不起作用,因为我不希望整个下拉列表在移动设备上不可见;我只希望它在点击而不是悬停时可见。

【问题讨论】:

  • 由于点击事件在 CSS 中不可行(还没有!),我们不能简单地使用 CSS 媒体查询来做到这一点。相反,使用 JavaScript 来获取浏览器的 UserAgent 字符串以检查与移动设备匹配的正则表达式,请参见此处:(stackoverflow.com/questions/11381673/…)
  • 请注意,大屏幕仍然可以是仅触控的(横向模式下的平板电脑)。这就是 Bootstrap 只使用触摸/点击事件的原因。
  • 您可以在浏览器中使用Modernizr to detect touch capabilityConsider this article,然而

标签: jquery html css responsive-design twitter-bootstrap-3


【解决方案1】:

您可以为此使用 javascript 事件。

使用移动支票库你可以说

var domObject = document.querySelector('.myClassOrIDWhateverFloatsYourBoat');
if(mobile checked is true){
    domObject.addEventListener('hover', function(){
        $('.dropdown-toggle').dropdown();  // http://getbootstrap.com/javascript/
    })
}else{
   domObject.addEventListener('click', function(){
        $('.dropdown-toggle').dropdown();  // http://getbootstrap.com/javascript/
    })
}

【讨论】:

    【解决方案2】:

    已编辑 @ouwen-huang 的答案很好,但是由于 jQuery 是 bootstrap.js 的依赖项,因此您最好使用 jQuery 方式,只需将要附加的所有事件添加到引号中,以空格分隔:

    $('.dropdown').on('mouseenter mouseleave click tap', function() {
      $(this).toggleClass("open");
    });
    

    选择器基于标准 Bootstrap 标记,直接取自文档,如下所示:

    <li class="dropdown">
        <a id="drop1" href="#" role="button" class="dropdown-toggle" data-toggle="dropdown">Dropdown <span class="caret"></span></a>
        <ul class="dropdown-menu" role="menu" aria-labelledby="drop1">
            <li role="presentation"><a role="menuitem" tabindex="-1" href="http://twitter.com/fat">Action</a></li>
            <li role="presentation"><a role="menuitem" tabindex="-1" href="http://twitter.com/fat">Another action</a></li>
            <li role="presentation"><a role="menuitem" tabindex="-1" href="http://twitter.com/fat">Something else here</a></li>
            <li role="presentation" class="divider"></li>
            <li role="presentation"><a role="menuitem" tabindex="-1" href="http://twitter.com/fat">Separated link</a></li>
        </ul>
    </li>
    

    这里的重点是,如果您使用的是支持鼠标的设备(例如没有触摸功能的桌面),则会触发 mouseenter/mouseleave 事件并且无需单击即可激活菜单。如果用户不在触发 mouseenter/mouseleave 事件的设备上,则当用户点击链接并且点击或点击处理程序处理下拉切换时触发点击或点击事件。

    已编辑以确保准确性。

    【讨论】:

    • 此解决方案意味着当您在桌面上时,如果您将鼠标悬停在该项目上,则会出现下拉菜单。如果单击它,下拉菜单就会消失。当您将鼠标悬停在另一个项目上时,它会出现,并且您单击的项目也会出现。菜单很快变得一团糟。
    • 我最近正在寻找这个确切的功能,并发现了一个可以智能地处理桌面和移动设备上的 Bootstrap 3 下拉菜单的插件:github.com/CWSpear/bootstrap-hover-dropdown
    【解决方案3】:

    其他 2 个解决方案有效,但不保留引导样式。一个更简单的解决方案是添加 'open' 类。

    $('.dropdown').on('mouseenter mouseleave click tap', function() {
      $(this).toggleClass("open");
    });
    

    【讨论】:

      【解决方案4】:

      这很简单,效果很好,但是在移动设备上,如果您打开子菜单并单击要关闭的菜单项,它不会关闭

      $('.dropdown').on('mouseenter mouseleave click tap', function() {
        $(this).toggleClass("open");
      });
      

      【讨论】:

        【解决方案5】:

        在尝试了许多通过 stackoverflow 发布的插件和解决方案后,我想出了相当简单的代码:

        • 通过原生 Bootstrap 类在悬停时显示下拉菜单(因此它与按钮单击配合得很好)
        • 设置 href 时使按钮链接起作用
        • 在移动设备上保持原始行为

        简单版

        $('ul.nav li.dropdown').hover(function() {
            if (!$('.navbar-toggle').is(':visible')) {
                $(this).toggleClass('open', true);
            }
        }, function() {
            if (!$('.navbar-toggle').is(':visible')) {
                $(this).toggleClass('open', false);
            }
        });
        $('ul.nav li.dropdown a').click(function(){
            if (!$('.navbar-toggle').is(':visible') && $(this).attr('href') != '#') {
                $(this).toggleClass('open', false);
                window.location = $(this).attr('href')
            }
        });
        

        $('.navbar-toggle').is(':visible') 检查我们当前是否在移动视图中, $(this).toggleClass('open', true) 添加或删除引导程序使用的 open css 类, window.location = $(this).attr('href') 将用户发送到链接 href 中设置的位置。


        要添加 jQuery 转换,我们必须稍微修改一下脚本。

        修改版

        visible = false;
        
        function toggleDropdown(dropdown, delay, fade, state) {
            if (state === undefined) visible = !visible
            else visible = state
        
            dropdown.children('.dropdown-menu').stop(true, true).delay(delay)[visible ? 'fadeIn' : 'fadeOut'](fade, function() {
                dropdown.toggleClass('open', visible);
                dropdown.children('.dropdown-toggle').attr('aria-expanded', visible);
                $(this).css('display', '');
            });
        }
        
        $('ul.nav li.dropdown').hover(function() {
            if ($('.navbar-toggle').is(':visible')) return;
            toggleDropdown($(this), 50, 100, true)
        }, function() {
            if ($('.navbar-toggle').is(':visible')) return;
            toggleDropdown($(this), 400, 200, false)
        });
        
        $('ul.nav li.dropdown a').click(function(){
            if ($('.navbar-toggle').is(':visible')) return;
            if ($(this).attr('href') != '#') {
                toggleDropdown($(this).parent(), 50, 100, false)
                window.location = $(this).attr('href')
            }
            else {
                toggleDropdown($(this).parent(), 50, 100)
            }
        });
        

        visible 变量可以在动画运行时重新悬停时使一切正常运行。

        【讨论】:

          【解决方案6】:
          // toggle dropdown on mouse hover, click and tap events
          $('.dropdown').on('mouseenter mouseleave click tap touchstart', function(event) {
              if (!$('.navbar-toggle').is(':visible')) {
                  $(this).dropdown('toggle');
              }
          });
          

          这是基于Bootstrap 3 documentation for Javascript Dropdowns. 的@jme11 答案的略微修改版本使用此方法的优点是它可以使下拉菜单完全按预期运行,而无需修改任何类,因此更清洁 IMO .

          Codepen Example

          【讨论】:

          • 这不能正常工作,特别是如果你有多个下拉菜单,你应该改用$(this)
          【解决方案7】:

          对于 Bootstrap 4,以下代码有效。

          $('.dropdown').on('mouseenter mouseleave click tap', function() {
              $(this).toggleClass("show");
          });
          

          【讨论】:

            【解决方案8】:

            实现此目的的一个好方法是仅在菜单未折叠时启用悬停。

            $('.dropdown').on('mouseenter mouseleave click tap', function(event) {
              if (!$('.navbar-toggle').is(':visible')) {
                $(this).toggleClass("open");
              }
            });
            

            【讨论】:

              猜你喜欢
              • 2021-01-28
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2020-06-07
              • 2019-10-30
              • 2023-03-19
              • 2014-01-25
              相关资源
              最近更新 更多