Reputation: 1792
I want to remove/add the classList
of some element if the classList
of another element is equal to "sth". But there is a little problem that it only runs the command once, I mean the condition doesn't check the classList
of the first element every second so it runs it without any problem. If the if is true then it runs the if condition and then it won't check else if and so reverse.
Here is my code:
const dToggle = () => {
const firstElm = document.querySelector('.firstElm');
firstElm.classList.toggle('red-border');
};
document.querySelector('button').addEventListener('click', dToggle);
const orangeOrRed = () => {
const firstElm = document.querySelector('.firstElm');
const secondElm = document.querySelector('.secondElm');
firstElm.classList === 'red-border' ? secondElm.classList.add('red') : secondElm.classList.add('orange');
// if (firstElm.classList === 'red-border') {
// secondElm.classList.remove('orange');
// secondElm.classList.add('red');
// } else if (firstElm.classList === 'orange-border' {
// secondElm.classList.remove('red');
// secondElm.classList.add('orange');
// };
};
// Maybe the exact problem is right here.
window.addEventListener('load', orangeOrRed);
console.log(document.querySelector('.secondElm').classList.value);
.d-none {
display: none !important;
}
.firstElm {
margin-top: 10px;
width: 200px;
height: 100px;
background-color: blue;
}
.orange-border {
border: orange 3px solid;
}
.red-border {
border: red 3px solid;
}
.secondElm {
margin-top: 10px;
width: 200px;
height: 100px;
background-color: green;
}
.orange {
background-color: orange !important;
}
.red {
background-color: red !important;
}
<button type="button" style="cursor: pointer;">Click here.</button>
<p>It should run the conditional statement whenever I click on the button to apply the border.</p>
<p> First Elm Border Color (MUST BE) Second Elm Background Color</p>
<div class='firstElm orange-border'></div>
<div class='secondElm'></div>
<p style="padding-bottom: 10px;">Remember that I only want to do this with(conditioal statements), It's possible either with classList.toggle() but I don't want to.</p>
Upvotes: 1
Views: 66
Reputation: 1643
Here we have three problems:
classList is a DOMTokenList that has a contains method which returns true if the element has the desired className or vice versa
you need to remove the orange
className if you want to add the red
className and vice versa
orangeOrRed
function runs only onceThe orangeOrRed
function runs only once on window's load event
You need to add the same event listener to the button's click event
const dToggle = () => {
const firstElm = document.querySelector('.firstElm');
firstElm.classList.toggle('red-border');
};
document.querySelector('button').addEventListener('click', dToggle);
const orangeOrRed = () => {
const firstElm = document.querySelector('.firstElm');
const secondElm = document.querySelector('.secondElm');
if (firstElm.classList.contains('red-border')) {
secondElm.classList.remove('orange');
secondElm.classList.add('red');
} else if (firstElm.classList.contains('orange-border')) {
secondElm.classList.remove('red');
secondElm.classList.add('orange');
};
};
// You're right, the exact problem is right here.
window.addEventListener('load', orangeOrRed);
document.querySelector('button').addEventListener('click', orangeOrRed);
console.log(document.querySelector('.secondElm').classList.value);
.d-none {
display: none !important;
}
.firstElm {
margin-top: 10px;
width: 200px;
height: 100px;
background-color: blue;
}
.orange-border {
border: orange 3px solid;
}
.red-border {
border: red 3px solid;
}
.secondElm {
margin-top: 10px;
width: 200px;
height: 100px;
background-color: green;
}
.orange {
background-color: orange !important;
}
.red {
background-color: red !important;
}
<button type="button" style="cursor: pointer;">Click here.</button>
<p>It should run the conditional statement whenever I click on the button to apply the border.</p>
<p> First Elm Border Color (MUST BE) Second Elm Background Color</p>
<div class='firstElm orange-border'></div>
<div class='secondElm'></div>
<p style="padding-bottom: 10px;">Remember that I only want to do this with(conditioal statements), It's possible either with classList.toggle() but I don't want to.</p>
Achieving the same results using the MutationObserver API.
It's useful when you have no toggle button or when you're not in control of when the class name of the element changes.
const firstElm = document.querySelector('.firstElm');
const secondElm = document.querySelector('.secondElm');
const orangeOrRed = () => {
if (firstElm.classList.contains('red-border')) {
secondElm.classList.remove('orange');
secondElm.classList.add('red');
} else if (firstElm.classList.contains('orange-border')) {
secondElm.classList.remove('red');
secondElm.classList.add('orange');
};
}
// Callback function to execute when mutations are observed
const callback = (mutationsList) => {
// check to see if the changed attribute that caused the mutationObserver callback to be called is the class attribute and run the desired code
if (mutationsList[0].attributeName === 'class') orangeOrRed();
};
// Create an observer instance linked to the callback function
const observer = new MutationObserver(callback);
// Options for the observer (which mutations to observe)
// Here the MutationObserver will call the specified callback just if attributes of the target node have changed
const config = { attributes: true, childList: false, subtree: false };
// Start observing the target node (firstElm) for configured mutations
observer.observe(firstElm, config);
const dToggle = () => {
firstElm.classList.toggle('red-border');
};
document.querySelector('button').addEventListener('click', dToggle);
// You're right, the exact problem is right here.
window.addEventListener('load', orangeOrRed);
.d-none {
display: none !important;
}
.firstElm {
margin-top: 10px;
width: 200px;
height: 100px;
background-color: blue;
}
.orange-border {
border: orange 3px solid;
}
.red-border {
border: red 3px solid;
}
.secondElm {
margin-top: 10px;
width: 200px;
height: 100px;
background-color: green;
}
.orange {
background-color: orange !important;
}
.red {
background-color: red !important;
}
<button type="button" style="cursor: pointer;">Click here.</button>
<div class='firstElm orange-border'></div>
<div class='secondElm'></div>
<p style="padding-bottom: 10px;">Remember that I only want to do this with(conditioal statements), It's possible either with classList.toggle() but I don't want to.</p>
Upvotes: 2
Reputation: 21485
You've misinterpreted what the problem is here; it's not that the conditional isn't running, it's that it's checking the wrong thing.
You're looking to see if a DOM element's classList === 'orange-border'
but this will never be true; classList isn't a simple string. What you want is to see if the classList includes orange-border.
const dToggle = () => {
const firstElm = document.querySelector('.firstElm');
firstElm.classList.toggle('red-border');
};
document.querySelector('button').addEventListener('click', dToggle);
const orangeOrRed = () => {
const firstElm = document.querySelector('.firstElm');
const secondElm = document.querySelector('.secondElm');
// I'm not sure why you have both this ternary and the similar if:else below, but I've fixed both to at least be checking the classList correctly:
firstElm.classList.contains('red-border') ? secondElm.classList.add('red') : secondElm.classList.add('orange');
if (firstElm.classList.contains('red-border')) {
secondElm.classList.remove('orange');
secondElm.classList.add('red');
} else if (firstElm.classList.contains('orange-border')) {
secondElm.classList.remove('red');
secondElm.classList.add('orange');
};
};
window.addEventListener('load', orangeOrRed);
console.log(document.querySelector('.secondElm').classList.value);
.d-none {
display: none !important;
}
.firstElm {
margin-top: 10px;
width: 200px;
height: 100px;
background-color: blue;
}
.orange-border {
border: orange 3px solid;
}
.red-border {
border: red 3px solid;
}
.secondElm {
margin-top: 10px;
width: 200px;
height: 100px;
background-color: green;
}
.orange {
background-color: orange !important;
}
.red {
background-color: red !important;
}
<button type="button" style="cursor: pointer;">Click here.</button>
<p>It should run the conditional statement whenever I click on the button to apply the border.</p>
<p> First Elm Border Color (MUST BE) Second Elm Background Color</p>
<div class='firstElm orange-border'></div>
<div class='secondElm'></div>
<p style="padding-bottom: 10px;">Remember that I only want to do this with(conditioal statements), It's possible either with classList.toggle() but I don't want to.</p>
Upvotes: 1