【问题标题】:Bootstrap Avoid navbar-toggle button to close opened sub menus on mobileBootstrap 避免导航栏切换按钮以关闭移动设备上打开的子菜单
【发布时间】:2019-10-06 02:19:09
【问题描述】:

我有一个基于 Bootstrap 3.3.7 的代码
我的菜单上有不同的菜单项和子菜单,我想让所有子菜单项在手机上打开,意味着不需要点击任何菜单项来显示它的子菜单,所以我写了一个 JS 代码来打开所有移动设备上的子菜单:

function opensubmenus() {
  if ($(window).width() < 768) {
    $("#top-navbar-collapse li").addClass('open');
  } else {
    $("#top-navbar-collapse li").removeClass('open');
  }
}

$(window).resize(opensubmenus);
opensubmenus();

但问题是当我单击导航栏切换按钮时,它会关闭所有子菜单,但我需要在移动设备上始终保持它们打开 你可以在这个网站上查看我的在线示例:https://dedidata.com

这里我截图了:https://pasteboard.co/IfSMCIu.jpg

我不喜欢完全禁用导航栏切换按钮,我需要它来切换整个导航栏,但我不喜欢它关闭子菜单,我的 JS 代码打开子菜单,但导航栏切换关闭那些子菜单

【问题讨论】:

  • 这将是一个很好的菜单外观和您想要实现的最小示例......
  • 听起来你有一个“关闭所有子菜单”函数被附加的 onclick 事件侦听器在某处调用。您能否提供更多您的导航条代码让我们看看它是如何工作的?

标签: javascript jquery twitter-bootstrap


【解决方案1】:

这个sn-p会应用到所有的下拉菜单,你可以修改它以获得你需要的下拉菜单。

我会解释它的作用:

const targets = document.getElementsByClassName('dropdown-toggle');

for(let i = 0; i < targets.length; i++) {
  targets[i].addEventListener('click', () => {
    targets[i].hasAttribute('data-toggle') &&
      targets[i].removeAttribute('data-toggle');

    // Managing locally the open and close
    targets[i].parentElement.classList.toggle('open');    
  });
}

第一行:

const targets = document.getElementsByClassName('dropdown-toggle');

我们得到所有类名为dropdown-toggle的元素(这用于下拉菜单的boostrap)

对于每个元素,我们附加一个click 侦听器,以便在用户单击下拉菜单时能够“手动”管理下拉菜单。

这是按行管理的:targets[i].parentElement.classList.toggle('open');

避免自动关闭菜单的重要方法是删除属性data-toggle

targets[i].hasAttribute('data-toggle') &&
          targets[i].removeAttribute('data-toggle');

如果您只有一个人在手机上应用这样的解决方案,您可以使用is.js 来检查您何时使用手机 (android/ios)

更新

此更新将自动打开菜单:

const menuItems = document.getElementsByClassName('navbar-toggle');

for (let i = 0; i < menuItems.length; i++) {
  menuItems[i].hasAttribute('data-toggle') && menuItems[i].addEventListener('click', () => {    
    const elements = document.getElementsByClassName('dropdown-toggle');
    for (let i = 0; i < elements.length; i++) {
      elements[i].hasAttribute('data-toggle') && elements[i].removeAttribute('data-toggle');      
      elements[i].parentElement.classList.add('open');
    }
  });
}

【讨论】:

  • 感谢您对我的问题的回复,您的代码实际上解决了我的问题,我只是想知道为什么我提到的代码在我调整窗口大小时会打开那些子菜单,但它没有打开那些子菜单当窗口从一开始就低于 768 时,这意味着它仅适用于调整大小,您的帮助将非常有用,但是您现在也明白了,我更新了网站,现在可以使用了
  • 您希望子菜单自动打开吗?我提供的解决方案依赖于用户操作来打开/关闭菜单并避免通过引导程序覆盖该状态。但是打开子菜单很容易更新。
【解决方案2】:

以下代码在navbar-toggle 上发生点击时展开子菜单 并根据子菜单的打开/关闭状态将aria-expanded更改为正确的值

function opensubmenus() {
    if ($(window).width() < 768) {
        $("#top-navbar-collapse li").addClass('open');
        $("#top-navbar-collapse li a").attr('aria-expanded','true');
    }else{
        $("#top-navbar-collapse li").removeClass('open');
        $("#top-navbar-collapse li a").attr('aria-expanded','false');
    }
}

$('#top-menu .navbar-toggle').click(function(){
    setTimeout(opensubmenus, 100);
});

$(window).resize(opensubmenus);
opensubmenus();

感谢@abelito 的提示

【讨论】:

    【解决方案3】:

    修改 10 分钟后的直码。我绝对不建议将其作为最终答案,但这将使您走上实现它的一种方式:

    function delayedSubmenuOpen() { setTimeout(openAllSubmenus, 100); }
    
    function openAllSubmenus() {
        var eles = document.getElementsByClassName("dropdown-toggle");
        for (i = 0; i < eles.length; i++) { 
            eles.item(i).parentElement.className += " open";
        }
    }
    
    var navigationHamburger = document.getElementsByClassName("navbar-toggle").item(0);
    navigationHamburger.addEventListener("click", delayedSubmenuOpen);
    

    我肯定会用跨浏览器兼容的 jQuery 调用来替换所有这些,因为我是在直接的 javascript 中完成的,并且只在我的 Chrome 浏览器中进行了测试。

    我也会考虑只编辑 CSS 而不是依赖 javascript 来执行此操作 - 也许在页面加载时,制作“.open”类的重命名副本并将其添加到所有具有类名的元素“ menu-item-has-children”——这样它就不能被 javascript 关闭。听起来你可能已经尝试过了,但绝对值得研究,而不是依赖于一些 hokey JS。

    【讨论】:

    • 您的代码完全符合我的需要,我只是将超时更改为 1,您为什么设置超时?视觉运动?您能否按照您的建议提供 jQuery 代码?我更喜欢只在顶部菜单上做公开活动,所以你认为我们可以做到吗?非常感谢,你现在明白了
    • 有没有办法在 a 标签上也将内部 aria-expanded="false" 更改为 true?
    • 没有超时,我的计算机没有扩展可能是由于汉堡按钮中的一些挥之不去的 javascript 来自动关闭它。大多数手机可能会遇到同样的问题,因为它们的处理速度不是很快,最终可能不会为它们扩展,但是 100 - 200 毫秒的延迟应该有足够的时间让 javascript 完成并让您安全地自动扩展.是的,我也会调用 .setAttribute("aria-expanded", false) 到任何有意义的元素
    【解决方案4】:

    将此添加到您的 css

    @media only screen and (max-width: 768px) {
        .megamenu .dropdown ul.dropdown-menu {
            display: block;
            position: static;
            float: none;
            width: auto;
            margin-top: 0;
            background-color: transparent;
            border: 0;
            -webkit-box-shadow: none;
            box-shadow: none;
        }
        .navbar-fixed-top .navbar-collapse {
            background-color: rgba(0, 0, 0, 0.7)!important;
        }
    
    }
    

    然后把函数改成这样

    function opensubmenus() {
      if (jQuery(window).width() < 768) {
        jQuery("#top-navbar-collapse").addClass('in');
      } else {
        jQuery("#top-navbar-collapse").removeClass('in');
      }
    }
    
    jQuery(window).resize(opensubmenus);
    opensubmenus();
    

    【讨论】:

    • 感谢您对我的问题的回复,您的代码完全禁用了导航栏切换,我不喜欢完全禁用它,我需要它来切换整个导航栏,但我不喜欢它关闭了子菜单,我的 JS 代码打开了子菜单,但是 navbar-toggle 关闭了这些子菜单,顺便说一句,我正在等待您的编辑,谢谢
    猜你喜欢
    • 2015-03-13
    • 1970-01-01
    • 2019-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-12
    • 1970-01-01
    相关资源
    最近更新 更多