I have a code based on Bootstrap 3.3.7
There are different menu items and sub menus on my menu, I want to have all sub menu items to be open on mobile, Means no need to click on any menu items to display it's sub menus, So I wrote a JS code to open all sub menus on mobile:
function opensubmenus() {
if ($(window).width() < 768) {
$("#top-navbar-collapse li").addClass('open');
} else {
$("#top-navbar-collapse li").removeClass('open');
}
}
$(window).resize(opensubmenus);
opensubmenus();
But the problem is when I click on a navbar-toggle button, It closes all submenus, But I need to keep them open on mobile devices all the time You can check my online sample on this site: https://dedidata.com
Here I have shown a screenshot: https://pasteboard.co/IfSMCIu.jpg
I don't like to disable navbar-toggle button completely, I need it to toggle the whole navbar, But I don't like it close the submenus, My JS code opens the submenus, But navbar-toggle closes those submenus
This snippet will be applied to all dropdowns, you can modify it to get what dropdowns you need.
I will explain what it does:
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');
});
}
First line:
const targets = document.getElementsByClassName('dropdown-toggle');
we get all the elements with class name dropdown-toggle
(this is used in boostrap for dropdowns menus)
For each element, we attach a click
listener to be able to manage "manually" dropdowns if the dropdown menu is clicked by the user.
This is managed by line: targets[i].parentElement.classList.toggle('open');
And the important one to avoid auto closing menus is to remove the attribute data-toggle
.
targets[i].hasAttribute('data-toggle') &&
targets[i].removeAttribute('data-toggle');
If you only one apply a solution like this for mobiles you can use is.js to check when you are in mobile (android/ios)
UPDATE
This update will open the menus automatically:
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');
}
});
}
The following code expands the sub menus when a click occurs on navbar-toggle
and it change the aria-expanded
to the correct value based on the open/close state of sub menu
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();
Thanks to @abelito for his hint
Straight code after tinkering for 10 minutes. I definitely don't recommend this as a final answer, but this will get you on the track towards one way of accomplishing it:
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);
I would definitely replace all of these with cross-browser compliant jQuery calls, as I did it in straight javascript and only tested in my browser on Chrome.
I'd also look into just editing the CSS instead rather than relying on javascript to do this -- maybe on page load, make a renamed copy of the ".open" class and add it to all elements with the classname "menu-item-has-children" -- this way it can't be toggled off by the javascript. Sounds like you may have tried this but definitely worth looking into rather than depending on some hokey JS.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With