I am trying to make a navigation menu I did all the HTML and CSS when come to javascript I am struck in the middle I am able to add a class to the
You can use "pure" JavaScript Element.classList
to add and remove a class from your DOM element.
add
: Add specified class values. If these classes already exist in attribute of the element, then they are ignored.
remove
: Remove specified class values.
Use Document.querySelectorAll()
to returnsa elements within the document that match the specified group of CSS selectors.
More info at:
https://developer.mozilla.org/en/docs/Web/API/Element/classList
https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll
Regarding your code, you can mark as active your element when User click on it using the following code:
window.myFunction = function(event) {
// reset all menu items
document.querySelectorAll('ul li a.active').forEach(function(item) {
item.classList.remove('active');
})
// mark as active selected menu item
event.target.classList.add("active");
};
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
header {
width: 100%;
height: auto;
max-width: 600px;
margin: 0 auto;
}
nav {
width: 100%;
height: 40px;
background-color: cornflowerblue;
}
ul {
list-style-type: none;
}
li {
display: inline-block;
}
a {
text-decoration: none;
padding: 8px 15px;
display: block;
text-transform: capitalize;
background-color: darkgray;
color: #fff;
}
a.active {
background-color: cornflowerblue;
}
.active {
ackground-color: red;
}
<header>
<nav>
<ul onclick="window.myFunction(event)">
<li><a href="#">home</a></li>
<li><a href="#">about</a></li>
<li><a href="#">service</a></li>
<li><a href="#">profile</a></li>
<li><a href="#">portfolio</a></li>
<li><a href="#">contact</a></li>
</ul>
</nav>
</header>
Use document.querySelectorAll
to find the element which currently have the active
class, then you can remove that class.
function myFunction(e) {
var elems = document.querySelectorAll(".active");
[].forEach.call(elems, function(el) {
el.classList.remove("active");
});
e.target.className = "active";
}
JSFIDDLE
Instead of document.querySelectorAll
you can also use document.querySelector
function myFunction(e) {
var elems = document.querySelector(".active");
if(elems !==null){
elems.classList.remove("active");
}
e.target.className = "active";
}
JSFIDDLE 2
Edit
Instead of iterating through the entire collection you can select the element which have a class active
using document.queryselector. Also provide an id
to the ul so that you can target the specific element
function myFunction(e) {
if (document.querySelector('#navList a.active') !== null) {
document.querySelector('#navList a.active').classList.remove('active');
}
e.target.className = "active";
}
<style type="text/css">* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
header {
width: 100%;
height: auto;
max-width: 600px;
margin: 0 auto;
}
nav {
width: 100%;
height: 40px;
background-color: cornflowerblue;
}
ul {
list-style-type: none;
}
li {
display: inline-block;
}
a {
text-decoration: none;
padding: 8px 15px;
display: block;
text-transform: capitalize;
background-color: darkgray;
color: #fff;
}
a.active {
background-color: cornflowerblue;
}
<title>Navigation class Toggling</title>
<header>
<nav>
<ul onclick="myFunction(event)" id='navList'>
<li><a href="#">home</a></li>
<li><a href="#">about</a></li>
<li><a href="#">service</a></li>
<li><a href="#">profile</a></li>
<li><a href="#">portfolio</a></li>
<li><a href="#">contact</a></li>
</ul>
</nav>
</header>
window.myFunction = function(event) {
var elms = document.querySelectorAll('ul li a');
// reset all you menu items
for (var i = 0, len = elms.length; i < len; i++) {
elms[i].classList.remove('active');
}
// mark as active clicked menu item
event.target.classList.add("active");
};
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
header {
width: 100%;
height: auto;
max-width: 600px;
margin: 0 auto;
}
nav {
width: 100%;
height: 40px;
background-color: cornflowerblue;
}
ul {
list-style-type: none;
}
li {
display: inline-block;
}
a {
text-decoration: none;
padding: 8px 15px;
display: block;
text-transform: capitalize;
background-color: pink;
color: #fff;
}
a.active {
background-color: blue;
}
.active {
ackground-color: red;
}
<header>
<nav>
<ul onclick="window.myFunction(event)">
<li><a href="#">home</a></li>
<li><a href="#">about</a></li>
<li><a href="#">service</a></li>
<li><a href="#">profile</a></li>
<li><a href="#">portfolio</a></li>
<li><a href="#">contact</a></li>
</ul>
</nav>
</header>
Below should help.
//Remove all classes by ID
document.getElementById("elementIdHere").className = "";
//If you wish to keep some classes on the element, use below
document.getElementById("elementIdHere").className = "keepClass";
You could use classList methods to add
, remove
, or toggle
.
First remove class name from previous one:
// assuming there's only one with such class name
// otherwise you need querySelectorAll and a loop
document.querySelector('.active').classList.remove('active')
Then add it to the new element:
e.target.classList.add('active')
HTML
<div class="container">
<nav>
<ul class="nav">
<li class="nav__item"><a class="nav__link active" href="#">Home</a></li>
<li class="nav__item"><a class="nav__link" href="#">Item 1</a></li>
<li class="nav__item"><a class="nav__link" href="#">Item 2</a></li>
<li class="nav__item"><a class="nav__link" href="#">Item 3</a></li>
<li class="nav__item"><a class="nav__link" href="#">Item 4</a></li>
<li class="nav__item"><a class="nav__link" href="#">Item 5</a></li>
</ul>
</nav>
</div>
CSS
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
*::before, *::after {
box-sizing: border-box;
}
.container {
width: 100%;
max-width: 1024px;
display: block;
margin: 30px auto;
}
ul {
list-style: none;
}
a {
text-decoration: none;
}
.nav {
display: flex;
flex-direction: row;
justify-content: space-around;
align-items: center;
}
.nav__item {
padding: 1rem;
}
.nav__link {
display: block;
padding: .3125rem 1.5rem;
text-transform: uppercase;
}
.nav__link.active {
border: 1px solid #ff4b4c;
color: #ff4b4c;
}
JS
document.addEventListener('DOMContentLoaded', function() {
const selector = '.nav__link';
const elems = Array.from(document.querySelectorAll(selector));
const navigation = document.querySelector('nav');
function makeActive(evt) {
const target = evt.target;
if (!target || !target.matches(selector)) {
return;
}
elems.forEach(elem => elem.classList.remove('active'));
evt.target.classList.add('active');
};
navigation.addEventListener('mousedown', makeActive);
});
BTW: A great solution is here: https://gomakethings.com/getting-all-sibling-elements-when-a-link-or-button-is-clicked-with-vanilla-js/