Jump to content

Off-Canvas Menu


brawn14

Recommended Posts

Iv applied the W3school Off Canvas Menu to a button. I would like to create multiple buttons which each open there own different off canvas panel. Does anyone know they best/correct way to apply this?

I can do this in Bootstrap but id rather not have to deal with the bootstrap customisation and would rather keep, i'm fairy new to JS so im just looking for suggestions to look into at the minute. Any help would be great.

Link to comment
Share on other sites

I found the menu you're talking about: https://www.w3schools.com/howto/howto_js_off-canvas.asp

To make the smallest amount of changes to W3Schools' existing code, you can pass the id of the element as an argument to the functions and then update the functions to use the variable instead of a fixed id. After that, you have to add some additional code to make sure that all of the other menus are closed except for the one you clicked on.

HTML:

<div id="sidenav1" class="sidenav">
  <a href="javascript:void(0)" class="closebtn" onclick="closeNav('sidenav1')">&times;</a>
  ...
</div>
<div id="sidenav2" class="sidenav">
  <a href="javascript:void(0)" class="closebtn" onclick="closeNav('sidenav2')">&times;</a>
  ...
</div>
<div id="sidenav3" class="sidenav">
  <a href="javascript:void(0)" class="closebtn" onclick="closeNav('sidenav3')">&times;</a>
  ...
</div>


<span onclick="openNav('sidenav1')">Menu 1</span>
<span onclick="openNav('sidenav2')">Menu 2</span>
<span onclick="openNav('sidenav3')">Menu 3</span>

Updating the functions to use a variable id:

/* Set the width of the side navigation to 250px and the left margin of the page content to 250px */
function openNav(id) {
  // Close any menus which are currently opened
  var sidenavs = document.getElementsByClassName("sidenav");
  for(let i = 0; i < sidenavs.length; i++) {
    sidenavs[i].style.width = "0";
  }

  // The rest of the code
  document.getElementById(id).style.width = "250px";
  document.getElementById("main").style.marginLeft = "250px";
}

/* Set the width of the side navigation to 0 and the left margin of the page content to 0 */
function closeNav(id) {
  document.getElementById(id).style.width = "0";
  document.getElementById("main").style.marginLeft = "0";
}

 

Link to comment
Share on other sites

Thanks Ingolme,

This is exactly what I was after.

Is there a way to apply a toggleNav to each button here also? Essentially creating 3 ways to close the panels:

  1. Closing by opening another off-canvas menu (e.g. clicking the 'Menu 2' button) -Addressed above.
  2. Closing by the within the off-canvas menu (clicking the '&times' button) - Also working.
  3. Closing by clicking the same button ('Menu 1' button)

I appreciate your help on this.

Link to comment
Share on other sites

I think the most robust solution is to use data attributes to keep track of whether a menu is open or not.

/* Set the width of the side navigation to 250px and the left margin of the page content to 250px */
function openNav(id) {
  let menu = document.getElementById(id);
  
  // Test if the menu is open
  let isOpen = menu.getAttribute("data-open");
  
  // Only open the menu if it was not already open
  if(isOpen) {
    closeNav(id);
  } else {
    // Close any menus which are currently opened
    var sidenavs = document.getElementsByClassName("sidenav");
    for(let i = 0; i < sidenavs.length; i++) {
      // Close the menus
      sidenavs[i].style.width = "0";

      // Mark the closed menus as not open
      sidenavs[i].removeAttribute("data-open");
    }
    
    // Open the menu and mark it as open
    menu.style.width = "250px";
    document.getElementById("main").style.marginLeft = "250px";
    menu.setAttribute("data-open", "1");

  }
}

/* Set the width of the side navigation to 0 and the left margin of the page content to 0 */
function closeNav(id) {
  let menu = document.getElementById(id);
  
  // Close the menu
  menu.style.width = "0";
  document.getElementById("main").style.marginLeft = "0";
  
  // Mark the menu as not open
  menu.removeAttribute("data-open");
}

 

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...