Lets say you have three elements, all white or no color applied at all. if any element clicked/selected it turns red, If any two elements clicked/selected they're red & green. If all three elements clicked/selected they're red, green, blue. Now when any element is clicked a second time it will turn back to white, but no matter what they still need to follow theses rules.
1 element = red
2 element = red, green
3 element = red, green, blue
With help I have so far came up with this code but cannot figure out how to make the event react based on the conditions needed. For example if all three are clicked and we click to remove the green color, then the blue will need to be green. jsFiddle with classes example
css
.container {
background-color: #ffffff;
border: 1px solid blue;
border-radius: 10px;
width: 100px;
height: 50px;
}
.red { background-color: #ff0000; }
.green { background-color: #00ff00; }
.blue { background-color: #0000ff; }
elements
<div class='container' id='1' style='margin: 150px 0 0 75px; float: left;'></div>
<div class='container' id='2' style='margin: 150px 0 0 175px; float: left;'></div>
<div class='container' id='3' style='margin: 150px 0 0 220px; float: left;'></div>
Javascript
window.onload=function () {
// set color classes into an array
var classes = ["red", "green", "blue"];
var nextClass = 0;
var element = document.querySelectorAll( ".container" );
// loop through container class elements one at a time onclick run changeClass
for ( var i = 0; i < element.length; i++ )
{
element[i].addEventListener( "click", changeClass );
}
function changeClass ( eventListener )
{
var element = eventListener.currentTarget;
var currentClass = hasClass( element, classes );
if ( currentClass )
{
element.classList.remove( currentClass )
}
else
{
element.classList.add( classes[nextClass] );
nextClass = (nextClass + 1 ) % classes.length;
}
}//end function
function hasClass( element, classes )
{
// loop through classes array
for ( var i = 0; i < classes.length; i++ )
{
// onclick if all classes applied return currentClass
if ( element.classList.contains( classes[i] ) )
{
return classes[i];
}
}
}// end function
}//end onload
Is there a way to load these classes based on the conditions needed?
Could also load the colors inline using element.style.backgroundColor
, but still doesn't help me. The last person that helped me was very talented and I'm hoping for the same help :)... Have learned a lot so far but still stuck, close but just can't get it right.
Here is the code I came up with: See it in action My updated code jsFiddle
window.onload=function () {
var classes = ["red", "green", "blue"];
var nextClass = 0;
var element = document.querySelectorAll( ".container" );
for ( var i = 0; i < element.length; i++ )
{
element[i].addEventListener( "click", changeClass );
}
function changeClass ( eventListener )
{
var elementG = document.querySelector( '.green' );
var elementB = document.querySelector( '.blue' );
var elementR = document.querySelector( '.red' );
var element = eventListener.currentTarget;
var currentClass = hasClass( element, classes );
var red = removeRed( element, classes );
var green = removeGreen( element, classes );
if ( currentClass )
{
element.classList.remove( currentClass )
nextClass--;
if (nextClass < 0)
{
nextClass += classes.length;
}
}
else
{
element.classList.add( classes[nextClass] );
nextClass = (nextClass + 1 ) % classes.length;
}
if ( red && elementB != null )
{
elementB.classList.add( 'red' );
elementB.classList.remove( 'blue' );
}
else if ( red && elementB == null && elementG != null)
{
elementG.classList.add( 'red' );
elementG.classList.remove( 'green' )
}
if ( green && elementB != null )
{
elementB.classList.add( 'green' );
elementB.classList.remove( 'blue' );
}
}//end function
function hasClass( element, classes )
{
// loop through classes array
for ( var i = 0; i < classes.length; i++ )
{
// if all three classes
if ( element.classList.contains( classes[i] ) )
{
return classes[i];
}
}
}// end function
function removeRed( element, classes )
{
if ( element.classList.contains( classes[0] ) )
{
return classes[0];
}
}// end function
function removeGreen( element, classes )
{
if ( element.classList.contains( classes[1] ) )
{
return classes[1]
}
}
}//end onload
I think you need to also keep track of the order the elements were clicked. I would suggest you do this by keeping an object that will act as a sort of key/value pair, where the key is the "id" of the element clicking/unclicking, and the value is the number it was clicked (ie 1 = red, 2 = green, etc.).
Then, in changeClass(), when adding the class, you can also add to the object the number it was clicked at. When removing the class, you can unset the key in the object and iterate over the items in the object and decrement anything that had a higher value. This decrement will allow you to adjust the color/number of anything that was clicked after that button that was just "unclicked" (eg a blue button should turn green if you "unclick" the green button).
Might look something like this:
Initialize with this:
var state = {};
Do this when clicking (before incrementing nextclass):
state[element.id] = nextClass;
Do this when unclicking:
var removedNum = state[element.id];
delete state[element.id];
nextClass--;
if (nextClass < 0) { nextClass += classes.length; }
var i;
var keys = Object.keys(state);
for (i = 0; i < keys.length; i++) {
if (state[keys[i]] >= removedNum) {
// decrement only things after the button unclicked
var checkElement = document.getElementById(keys[i]);
state[keys[i]]--;
var checkClass = hasClass(checkElement, classes);
if (checkClass) {
// remove its existing class
checkElement.classList.remove(checkClass);
}
// add the one it should now have
checkElement.classList.add( classes[state[keys[i]]] );
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.