0

i have this

$(".picker").click(function(e) {
    var imgID = $(this).attr("data-imgID");
    $('body').addClass('picker-' + imgID);
});

<span class="taPicker" data-imgID="0"></span>
<span class="taPicker" data-imgID="1"></span>
<span class="taPicker" data-imgID="2"></span>

i want to toggle between generic classes on body element, for example if you click on .picker i want to add a unique class to body element based on the data-imgID attribute

But, how can i prevent the duplication's? for example if you click on another .picker i want to remove the previous class and add a new one

Nippledisaster
  • 278
  • 2
  • 18
  • 1
    Use the remove class function with a partial selector so it remove all the classes starting with `picker-` before adding the new one. See https://stackoverflow.com/questions/41832255/css-class-name-selector-name-starts-with – GillesC Jul 22 '20 at 09:42
  • Does this answer your question? [jQuery removeClass wildcard](https://stackoverflow.com/questions/2644299/jquery-removeclass-wildcard) – freedomn-m Jul 22 '20 at 09:47
  • 1
    @GillesC don't think you can use a wildcard with `.removeClass` - the link you've provided is for a selector, not an argument to removeClass - you can however use a function as shown here: [jQuery removeClass wildcard](https://stackoverflow.com/questions/2644299/jquery-removeclass-wildcard) (so the principle is the same) – freedomn-m Jul 22 '20 at 09:49
  • @freedomn-m Yeah can't use wildcard, haven't use jQuery in over 10 years so should have check the documentation first. But it doesn't just take function either, it can take a list of classes too as a string or an array. – GillesC Jul 23 '20 at 09:57

4 Answers4

3

In your case you could do something like this:

var selectedClass = null;
$(".taPicker").click(function(e) {
  var imgID = $(this).attr("data-imgID");
  $('body').addClass('picker-' + imgID);
  if (selectedClass != null) {
    $('body').removeClass(selectedClass);
  }
  selectedClass = 'picker-' + imgID;
});
body.picker-0 {
  background-color: pink;
}

body.picker-1 {
  background-color: red;
}

body.picker-2 {
  background-color: blue;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<span class="taPicker" data-imgID="0">click 0</span>
<span class="taPicker" data-imgID="1">click 1</span>
<span class="taPicker" data-imgID="2">click 2</span>

Here is a fiddle

freedomn-m
  • 27,664
  • 8
  • 35
  • 57
Roman
  • 3,563
  • 5
  • 48
  • 104
2

Another approach would be to determined the classes which need to be removed on each subsequent update. To this end, you can use a function which parses the current classes and removes any class which contains picker-, before setting the new class.

Here's what the JS code would look like:

function getPickerClasses(index, className) {
  return className.split(' ').filter((classItem) => classItem.includes('picker-'));
}

$(".taPicker").click(function(e) {
    var imgID = $(this).attr("data-imgID");
    
    $('body').removeClass(getPickerClasses).addClass('picker-' + imgID);
});

This way, before setting the new class, the old one is removed. Have a look at this fiddle to see the code in action: https://jsfiddle.net/0u24a1g3/

Dharman
  • 30,962
  • 25
  • 85
  • 135
Romi Halasz
  • 1,949
  • 1
  • 13
  • 23
1

It can be done without adding extra global variable

$(".taPicker").click(function(e) {
  var imgID = $(this).attr("data-imgID");
  $('body').removeClass(function() {
    return (this.className.match(/picker-./g) || []).join(' ');
  });
  $('body').addClass('picker-' + imgID);
});
body.picker-0 {
  background-color: pink;
}

body.picker-1 {
  background-color: red;
}

body.picker-2 {
  background-color: blue;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<span class="taPicker" data-imgID="0">click 0</span>
<span class="taPicker" data-imgID="1">click 1</span>
<span class="taPicker" data-imgID="2">click 2</span>
Jacek Rojek
  • 1,082
  • 8
  • 16
0

You can capture the original class(es) of body in a variable at DOM ready then use .removeClass() before re-adding back the original class plus the one based on the clicked element.

$(".taPicker").click(function(e) {
    var imgID = $(this).attr("data-imgID");
    var picker = $('body').attr("class").match(/picker-\d+/g) || [];
    $('body').removeClass(picker).addClass('picker-' + imgID);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<body class="original">
<span class="taPicker" data-imgID="0">0</span>
<span class="taPicker" data-imgID="1">1</span>
<span class="taPicker" data-imgID="2">2</span>
</body>
PeterKA
  • 24,158
  • 5
  • 26
  • 48
  • 2
    There could be a case where another body class is added somewhere else, then after next click on `picker` that would be ignored – Jacek Rojek Jul 22 '20 at 10:07