避免使用导航栏切换按钮来关闭移动设备上打开的子菜单

时间:2019-05-19 14:11:16

标签: javascript jquery twitter-bootstrap

我有一个基于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

我不喜欢完全禁用navbar-toggle按钮,我需要它来切换整个navbar,但是我不喜欢它关闭子菜单,我的JS代码打开了子菜单,但是navbar-toggle关闭了这些子菜单

4 个答案:

答案 0 :(得分:6)

此代码段将应用于所有下拉菜单,您可以对其进行修改以获取所需的下拉菜单。

我将解释其作用:

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');
    }
  });
}

答案 1 :(得分:4)

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的提示

答案 2 :(得分: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就无法将其关闭。听起来您可能已经尝试过这种方法,但绝对值得研究,而不是依赖于某些胡言乱语的JS。

答案 3 :(得分:1)

将此添加到您的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();