How can i minimize the code in a class toggler that targets nav?

I love clean code but I'm zero in javascript. I'd love to do two things to the super easy code below:

function nav_open() {
  var myNav = document.getElementById('nav_anim');
  if (myNav.className == 'nav_closed') {
    myNav.className = 'nav_open';
  } else {
    myNav.className = 'nav_closed';
  }
}
  1. Use getElementsByTagName to target the nav instead of giving it a useless id (in order to use only <nav> instead of <nav id="nav_anim"> in the body. I tried some combos but none of them works.
  2. Get rid of that ugly myNav name, is it mandatory? I know I can change it, but can I remove it? Is it possible to use something like nav.className=='nav_closed' or even better className=='nav_closed' instead of myNav.className=='nav_closed'

I would suggest keeping the id on your nav, targetting your DOM elements using ids or classes is something that is commonly done and can speed up lookup. Using getElementsByTagName() adds unnecessary complexity and would need to traverse your entire DOM to find your element, so it isn't very efficient, espeicially if you just have one nav element. If you really want to, you could use querySelector to select the first nav item:

const myNav = document.querySelector("nav");

At the end of the day though, if you want to interact with elements in your JavaScript code, you'll need to explicitly grab them (not counting named access on the global window object as it is recommended not to use this).


To further improve your toggle code, you could perform two toggles using DOMTokenList.toggle(), one to hide your first class and one to add your other. Every time you run both toggles, they will add/remove both classes depending on whether they exist or not:

const myNav = document.getElementById("nav_anim");
myNav.classList.toggle('nav_closed');
myNav.classList.toggle('nav_open');

See example below:

const btn = document.getElementById("btn");
btn.addEventListener("click", () => {
  btn.classList.toggle("on");
  btn.classList.toggle("off");
});
.on {
  background-color: lightgreen;
}

.off {
  background-color: red;
}
<button id="btn" class="on">Click me</button>

Depending on your code, you may even be able to remove the nav_closed class by targeting your nav element that does not have the nav_open class:

#nav_anim:not(.nav_open) {
  /* nav_closed styles */
}

With this setup, you can use just one toggle:

const myNav = document.getElementById("nav_anim");
myNav.classList.toggle('nav_open');

See example below:

const btn = document.getElementById("btn");
btn.addEventListener("click", () => {
  btn.classList.toggle("on");
});
.on {
  background-color: lightgreen;
}

#btn:not(.on) {
  background-color: red;
}
<button id="btn" class="on">Click me</button>