I want to toggle a css class on all elements with the same class, on click of another element.
I had it working with jQuery but need to switch to pure JavaScript.
The jQuery version that works:
$(function() {
$("#logo").click(function() {
$(".grey").toggleClass("white", 1000);
$(".red").toggleClass("orange", 1000);
});
});
When you click on the element with id="logo", everything with toggles "white" class and everything with toggles "orange".
CodePudding user response:
first grab the "id". Then Listen for a "click" event on that. When click occurs grab the all "white" class elements first. "queryselectorAll" returns an array-like NodeList, so you can use "forEach" array method on that. Then iterate the all elements one by one. Same logic goes for "red" class elements.
let logo = document.getElementById('logo');
logo.addEventListener('click', ()=>{
let grey = document.querySelectorAll('.grey');
grey.forEach((e)=>{
e.classList.toggle('white')
})
let red = document.querySelectorAll('.red');
red.forEach((e)=>{
e.classList.toggle('orange')
})
})
CodePudding user response:
Firstly, select the logo element by its id attribute. Register a click event listener on it to trigger the procedure. The event handler function will select all the elements containing the grey & red class names producing a list of nodes, iterate over them, and for each of those elements, toggle the white & orange class names in the list of classes.
const logo = document.getElementById('logo');
logo.addEventListener('click', () => {
const grey = document.querySelectorAll('.grey');
const red = document.querySelectorAll('.red');
grey.forEach(e => e.classList.toggle('white'));
red.forEach(e => e.classList.toggle('orange'));
}, false);
body {
background-color: #666;
}
.grey {
color: #bbb;
}
.red {
color: red;
}
.white {
color: white;
}
.orange {
color: orange;
}
<button id="logo">LOGO!</button>
<p >Hello World</p>
<p >Hello World</p>
<p >Hello World</p>
<p >Hello World</p>
<p >Hello World</p>
I hope this solves your problem.
CodePudding user response:
You can get an element by its class and then operate on it:
document.getElementById('logo').addEventListener('click', function(){
var redElements = document.getElementsByClassName('red');
Array.from(redElements).forEach(el => el.classList.toggle('orange'));
var greyElements = document.getElementsByClassName('grey');
Array.from(greyElements).forEach(el => el.classList.toggle('white'));
});
CodePudding user response:
Your code annotated with conversions to plain js:
$(function() // not even necessary in jQuery
$("#logo").click(function() {
// **replace with
document.querySelector(`#logo`).addEventListener(`click`, /*[you handler function]*/)
// your handler function
function myLogoHandler() {
$(".grey").toggleClass("white", 1000);
// ^ invalid/unnecessary parameter
// **replace with
document.querySelectorAll(`.grey`).forEach(el => el.classList.toggle(`white`));
/* ... etc */
}
There are several ways to handle this 'toggling'. Here are two examples using classList.replace. The snippets use event delegation. For the ...-syntax see MDN.
Why
replace? In your code for all.greyelements you'll end up with either<[element] >or<[element] >. That is confusing and may lead to unforeseen side effects (e.g. contradictory css values).Why
event delegation? It may look like overkill it this case, but for a dynamic webpage it's a way to handle dynamically created elements without having to reassign handlers to them, to do more with less (handling) code and it improves performance.
document.addEventListener(`click`, handle);
function handle(evt) {
// if the click originated from the button
if (evt.target.id === `toggle`) {
// find all elements with className green or red
document.querySelectorAll(`.green, .red`)
.forEach(el => {
// create parameters for the replace
// if current is red then red should be replaced by green
// otherwise green should be replaced by red
const colors = el.classList.contains(`red`)
? [`red`, `green`] : [`green`, `red`];
el.classList.replace(...colors);
// ^ spread the array into variables
})
}
}
.green:before {
content: 'Green';
color: green;
}
.red:before {
content: 'Red';
color: red;
}
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<button id="toggle">toggle color</button>
Add more flexibility using a data-attribute for the classnames to toggle.
document.addEventListener(`click`, handle);
function handle(evt) {
if (evt.target.id === `toggle`) {
// find all elements with the data-colors attribute
document.querySelectorAll(`[data-colors]`)
.forEach(el => {
// convert the data-colors value to array
const colors = el.dataset.colors.split(`,`);
el.classList.replace(...colors);
// swap the colors.
el.dataset.colors = colors.reverse();
// ^ note:
// the array is automatically converted
// to a string here
})
}
}
.green:before {
content: 'Green';
color: green;
}
.red:before {
content: 'Red';
color: red;
}
.orange:before {
content: 'Orange';
color: orange;
}
<div data-colors="green,orange"></div>
<div data-colors="red,green"></div>
<div data-colors="orange,red"></div>
<button id="toggle">toggle color</button>
CodePudding user response:
simplification of javascript is jquery so dont need to do it in hard way friend.
var grey = document.getElementByClassName("grey");
grey.classList.toggle("white");
