JordanBarber JordanBarber - 3 months ago 18
CSS Question

Using jQuery '.eq()' with multiple classes

How can I properly use the 'eq' function on multiple classes? Because, the div's with class 'a' are not subsequent, I cannot use the 'eq' function to updated their class. If the divs with class "b", are removed, the function works perfectly. Here's a fiddle https://jsfiddle.net/9w8zhg7d/4/. I have the following HTML:

<div class="a current">
</div>
<div class="a">
</div>
<div class="b">
</div>
<div class="b">
</div>
<div class="a">
</div>
<div class="a">
</div>


and the following javascript:

Class = {
a: ".a",
highlighted: ".a.current",
init: function() {
$(this.a).click(this.toggleA.bind(this));
},
toggleA: function(e) {
e.preventDefault();
$(this.highlighted).removeClass("current");
var target = $(e.target);
var clickedA = target.closest(this.a);
var clickedIndex = clickedA.index();
$(".a").eq(clickedIndex).addClass("current");
console.log(clickedIndex);
$(".b").eq(clickedIndex).css("display", "inline-block");
}
};

Class.init();


Any help is much appreciated!

Answer

If I understand your question correctly, you want to know the index of the particular .a element that was clicked, ignoring all other elements. If so you just have to use the .index() method correctly:

var clickedIndex = $(this.a).index(e.target);

When you call .index() with no arguments as in your code, it finds the index of the first element in the jQuery object relative to its siblings, not relative to other elements in the jQuery object. The code I've shown says to first select all of the .a elements, then within those elements only figure out the position of the e.target element.

You've also overcomplicated the setting of the current class - it doesn't make sense to use .closest(), because that is for navigating up through the DOM and all of your elements are siblings. You can just say:

$(e.target).addClass("current");

I don't understand how you want to apply the index of the clicked .a element to the .b elements, because there are four .a's and only two .b's, but still putting what I've said above together with your code gives something like this:

Class = {
  a: ".a",
  highlighted: ".a.current",
  init: function() {
    $(this.a).click(this.toggleA.bind(this));
  },
  toggleA: function(e) {
    e.preventDefault();
    $(this.highlighted).removeClass("current");
    var target = $(e.target).addClass("current");
    var clickedIndex = $(this.a).index(e.target);
    console.log(clickedIndex);
    $(".b").removeClass("current").eq(clickedIndex).addClass("current");
    $(".c").removeClass("current").eq(clickedIndex).addClass("current");
  }
}

Class.init();
.a,.b { width:50px; height:50px; background:black; display:inline-block; }
.c { width:20px; height:20px; background:blue; display:inline-block; }
.a.current{ background:red; }
.c.current, .b.current{ background:green; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="a current"></div>
<div class="a"></div>
<div class="b"></div>
<div class="b"></div>
<div class="a"></div>
<div class="a"></div>
<div class="related">
  <div class="c"></div> <div class="c"></div> <div class="c"></div> <div class="c"></div>
</div>

(Or an updated version of your fiddle: https://jsfiddle.net/9w8zhg7d/8/)