Click here to see the image I am new to javascript. I am trying to switch between the sections and I am getting a TypeError. Don't know what to do.
const sections = document.querySelectorAll('.section');
const sectBtns = document.querySelectorAll('.controls');
const sectBtn = document.querySelectorAll('.control');
const allSections = document.querySelector('.main-content');
function PageTransition() {
//Button click active class
for(let i = 0; i < sectBtn.length; i ) {
sectBtn[i].addEventListener('click', function(){
let currentBtn = document.querySelectorAll('.active-btn');
currentBtn[0].className =
currentBtn[0].className.replace('active-btn', '');
this.className = 'active-btn';
})
}
}
And here's my HTML code. I have element with the class name active-btn.
<body >
<header >
</header>
<main>
<section ></section>
<section ></section>
<section ></section>
<section ></section>
</main>
<div >
<div >
<i ></i>
</div>
<div data-id="about">
<i ></i>
</div>
<div data-id="portfolio">
<i ></i>
</div>
<div data-id="skills">
<i ></i>
</div>
<div data-id="contact">
<i ></i>
</div>
</div>
<script src="app.js"></script>
</body>
CodePudding user response:
The first time you try to get the active button, there aren't any elements with that class, so document.querySelectorAll just returns an empty array.
Then, when you try to access the first element, that returns undefined.
What causes the error is trying to access className on that undefined.
You can fix that by using optional chaining, so it only accesses the property if there's an element.
for(let i = 0; i < sectBtn.length; i ) {
sectBtn[i].addEventListener('click', function(){
// (1)
let currentBtn = document.querySelector('.active-btn');
// (2) (3) (4)
currentBtn?.classList.remove('active-btn');
this.classList.add('active-btn')
})
}
I changed this to
querySelectorinstead ofquerySelectorAllbecause you are only looking for the first result.This is the optional chaining. If
currentBtnisnullorundefined, then nothing will happen (no error).If it isn't
nullorundefined, then theactive-btnclass will be removed.This is changed to
classListinstead ofclassName, becauseclassListhas a better API.This is how you remove a class with
classList. If you want to read more about it, this is the MDN link.
I hope this helps! :)
