Home > OS >  How do i toggle between multiple classes for multiple elements in jQuery?
How do i toggle between multiple classes for multiple elements in jQuery?

Time:05-23

So I'm trying to implement a set of functions on my website with multiple div objects in it, so that when I click on Div A, it sets the text color of the page to red through Class A, and when i click on Div B, it sets the text to green through Class B, and so on and so forth.

My issue is that the other classes don't unset when clicking multiple objects and one class overrides the others, so the color of the text won't switch anymore.

I've been looking for solutions and trying to use addClass() and removeClass(), but it doesn't work for some reason. Here is a snippet of my code here

$(function() {
  $('.one').click(function() {
    $("h1").addClass('onetxt');
    $("h1").removeClass('twotxt, threetxt');
  });
});

$(function() {
  $('.two').click(function() {
    $("h1").addClass('twotxt');
    $("h1").removeClass('onetxt, threetxt');
  });
});

$(function() {
  $('.three').click(function() {
    $("h1").addClass('threetxt');
    $("h1").removeClass('onetxt, twotxt');
  });
});
h1 {
  text-align: center;
}

div {
  height: 65px;
  width: 65px;
  margin: 20px auto;
  border-style: solid;
}


/*style info, ignore above here*/

.one {
  background-color: red;
}

.onetxt {
  color: red;
}

.two {
  background-color: green;
}

.twotxt {
  color: green;
}

.three {
  background-color: blue;
}

.threetxt {
  color: blue;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<h1>Sample Text</h1>

<div ></div>
<div ></div>
<div ></div>

Any help on this would be greatly appreciated, and if you need more info, ask me in the replies, thank you!

EDIT: Here's a JSFiddle link demonstrating the code that i currently have, my intention is for all three of the DIV elements to change the top text's color when selected in any order, with using the classes if possible.

CodePudding user response:

It seems like the main issue is that removeClass doesn't support multiple class selectors (like 'onetxt, twotxt'). Also you aren't removing all possible classes depending on the order of clicks.

Here's a solution that might work. I've written some helper functions which hopefully clarify what's going on.

const targets = 'h1, p'
const classmap = {
  one: 'onetxt',
  two: 'twotxt',
  three: 'threetxt'
}
const allclasses = Object.values(classmap);

function clearSelection() {
  allclasses.forEach(function(clz) { $(targets).removeClass(clz) });
}

function addSelection(sel) {
    $(targets).addClass(classmap[sel]);
}

$(function() {  
    $('.one').click(function(){
      clearSelection();
      addSelection('one')
    });
});

  $(function() {  
    $('.two').click(function(){
      clearSelection();
      addSelection('two')
    });
});

  $(function() {  
    $('.three').click(function(){
      clearSelection();
      addSelection('three')
    });
});

CodePudding user response:

Here's a vanilla DOM API solution based on classList.toggle(className: string, force: boolean). The second parameter controls whether toggle works as remove or add.

const classes = ['one', 'two', 'three'];
classes.forEach(clazz => {
  document.querySelector(`.${clazz}`).addEventListener('click', () => {
    classes.forEach(cl => document.querySelector('h1').classList.toggle(`${cl}txt`, cl === clazz));
  })
})
h1 {
  text-align: center;
}

div {
  height: 35px;
  width: 35px;
  margin: 5px auto;
  border-style: solid;
}


/*style info, ignore above here*/

.one {
  background-color: red;
}

.onetxt {
  color: red;
}

.two {
  background-color: green;
}

.twotxt {
  color: green;
}

.three {
  background-color: blue;
}

.threetxt {
  color: blue;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<h1>Sample Text</h1>

<div ></div>
<div ></div>
<div ></div>

CodePudding user response:

There is no .removeClass() overload supports multiple argument, it only remove the first class. .removeClass() with no argument remove all the classes. This maybe the one you need.

I tweak your code a little bit, including:

  1. Rename some class name. .color-palette is the container of all color selection. .color is individual color choice box.
  2. Add data-color-name attribute to .color. The attribute will be used for sample-text css class assignment.
  3. Simplify the click event with a single, event-delegate handler. I try to decouple the add/remove class logic with the actual color name. This way if you have more color boxes to add, you do not need to copy a new set of function.
  4. Define custom css property. E.g. (--color-1, --color-2). The same property is used for color box background and sample text font color. You don’t have to maintain colors in two different place.

$('.color-palette').on('click', '.color', function(e) {
  $("#sample-text").removeClass().addClass($(e.currentTarget).data('color-name'));
});
/* maintain the color choices here */
:root {
  --color-1: red;
  --color-2: green;
  --color-3: blue;
}

h1 {
  text-align: center;
}

.color {
  height: 65px;
  width: 65px;
  margin: 20px auto;
  border-style: solid;
}


/* style info, ignore above here */


/* color palette style */

.color.color-1 {
  background-color: var(--color-1);
}

.color.color-2 {
  background-color: var(--color-2);
}

.color.color-3 {
  background-color: var(--color-3);
}


/* sample text style */

#sample-text.color-1 {
  color: var(--color-1);
}

#sample-text.color-2 {
  color: var(--color-2);
}

#sample-text.color-3 {
  color: var(--color-3);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<h1 id="sample-text">Sample Text</h1>
<div >
  <div  data-color-name="color-1"></div>
  <div  data-color-name="color-2"></div>
  <div  data-color-name="color-3"></div>
</div>

  • Related