0

Uncaught TypeError: Cannot read property 'toggle' of undefined

Here's the code:

HTML

<button onclick="toggleSidebar()"> </button>

JavaScript:

function toggleSidebar() {
 document.getElementsByClassName("sidebar").classList.toggle("active");
}

The button seems to be working fine when I console.log to check if it's being pressed. But, when I run the above code I keep getting that error. Help would be greatly appreciated!

aeskrek99
  • 3
  • 1
  • `document.getElementsByClassName` returns a collection of elements, a collection of elements does NOT have the property `classlist`, only an element has that ... but you have nothing with the class `sidebar` – Jaromanda X Jan 06 '20 at 11:18
  • You don't have any class specified in the button element so it will fail as there is no sidebar class in your example, then you de-reference the return of getElementsByClassName which will be undefined. – SPlatten Jan 06 '20 at 11:20
  • @Mamun `document.getElementsByClassName("sidebar")` seems to return `undefined` - otherwise the error would tell something like `toggle is not a function` – messerbill Jan 06 '20 at 11:20

1 Answers1

-1

.getElementsByClassName() returns a collection of matching elements. So, first you must have some elements that have the class specified.

Next, collections don't have a classList property. You must isolate an individual element to use classList, which you can do by passing an index to the returned collection:

button onclick="toggleSidebar()"> </button>

function toggleSidebar() {
 document.getElementsByClassName("sidebar")[0].classList.toggle("active");
}

With that said, you should not be using .getElementsByClassName() in the first place. Instead, use its modern counterpart, .querySelectorAll(). Additionally, you should not be setting up your events with inline HTML event attributes, like onclick. Events should be set up in JavaScript.

// Get reference to the buttons and set up click event handlers
document.getElementById("side1Toggle").addEventListener("click", toggleSidebar1);
document.getElementById("side2Toggle").addEventListener("click", toggleSidebar2);

function toggleSidebar1() {
  // If there is a specific single element you want to work with use .querySelector():
  document.querySelector(".sidebar1").classList.toggle("active");
}

function toggleSidebar2() {
  // If you want to work with all the matches use .querySelectorAll():
  document.querySelectorAll(".sidebar2").forEach(function(sidebar){
    sidebar.classList.toggle("active");
  });
}
.active { color:red; }
<button id="side1Toggle">Click to toggle sidebar 1 Class</button>
<div class="sidebar1">This is sidebar1.</div>

<button id="side2Toggle">Click to toggle sidebar 2 Class</button>
<div class="sidebar2">This is sidebar2.</div>
<div class="sidebar2">This is sidebar2.</div>
<div class="sidebar2">This is sidebar2.</div>
<div class="sidebar2">This is sidebar2.</div>
Scott Marcus
  • 64,069
  • 6
  • 49
  • 71
  • @messerbill That's because in the OP's supplied code, there were no matching elements, but that's not the real issue here. – Scott Marcus Jan 06 '20 at 11:36