I am trying to use JavaScript to change the background color of an element after being selected, and also to make sure that only one element at a time has the particular background color. Once the user selects on a different element I would like the previous element that was selected to be replaced by a different background color. Currently I am only able to toggle individual elements by selecting on EACH element. I need to be able to select on an element and apply the new background color, then have JavaScript change the background color of the previously active element to a different color (one less click).
What I am trying to do is very similar to modern navbars or list items where only one element at a time is “active” and has a background color that is different than the other elements in the same div, row, etc.
Notes about my work I am utilizing bootstrap and have no desire to use jQuery for this particular project.
CSS:
<!DOCTYPE html>
<html lang="en">
<head>
<style>
h4 {
border: 1px solid black;
border-radius: 8px;
padding: 10px 2px 10px 2px;
margin: 20px 20px 0px 20px;
background-color: #F0F0F0;
border-color: #F8F8F8;
color: #505050;
cursor: pointer;
}
.active {
background-color: #99E6FF;
}
</style>
</head>
</html>
HTML:
<div id="pTwoRowOne">
<div class="row">
<div class="col-md-4 row row-centered">
<h4 id="techBio" class="test">Biology</h4>
</div>
<div class="col-md-4 row row-centered">
<h4 id="techCart" class="test">Cartography</h4>
</div>
<div class="col-md-4 row row-centered">
<h4 id="techChem" class="test">Chemistry</h4>
</div>
</div>
</div>
JavaScript:
document.getElementById("techBio").onclick=function() {
document.getElementById("techBio").classList.toggle('active');
}
document.getElementById("techCart").onclick=function() {
document.getElementById("techCart").classList.toggle('active');
}
document.getElementById("techChem").onclick=function() {
document.getElementById("techChem").classList.toggle('active');
}
An example can be seen here: http://jsbin.com/fugogarove/1/edit?html,css,js,output
If clarification is needed let me know.
Yup, pretty straightforward.
Assumptions
classList
Example
JSBin
Code
I rewrote your JavaScript to make it a little bit cleaner and to DRY it up a bit:
var techs = [].slice.call(document.querySelectorAll('#pTwoRowOne h4'));
function set_active(event) {
techs.forEach(function(tech){
if (event.target == tech) { return; }
tech.classList.remove('active');
});
event.target.classList.toggle('active');
}
techs.forEach(function(item) {
item.addEventListener('click', set_active);
});
Some explanation
[].slice.call(document.querySelectorAll('#pTwoRowOne h4'));
– We're using this to change the output from a NodeList
to an Array
. This allows us to use forEach
later. querySelectorAll
returns a NodeList
that contains all elements matching the CSS selector. You can probably replace that with a better CSS selector depending on your environment.
addEventListener
is a much nicer way than the iterative add via onclick +=
to bind an event listener. It's also the recommended way (as far as I know) in ECMA5 and later.
By setting the element queries as variables, you'll be able to keep the reference in memory instead of polling the DOM every time to alter elements. That'll make your JavaScript marginally faster, and it's again just a nicer, cleaner version of the code which it produces.
updates
I reworked the JS to make more sense.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With