JordanBarber
JordanBarber

Reputation: 2101

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!

Upvotes: 0

Views: 829

Answers (2)

nnnnnn
nnnnnn

Reputation: 150070

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/)

Upvotes: 2

Phillip Chan
Phillip Chan

Reputation: 993

Okay, I feel like the solution you're proposing may be overcomplicated. Have you considered this solution?

HTML:

<div class="container">
    <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>

CSS:

.container {
    display: flex;
    flex-wrap: wrap;
    width: 100%;
}

.container > div {
  width:50px;
  margin: 1em;
  height:50px;
  background:black;
}

.a.current{
  background:red;
}

Javascript:

$('.container > div').on('click', function() {
    $('.container > div').removeClass("current");
    $(this).addClass('current')
});

This will just apply .current to the one clicked and while removing it from all. Targeting the parent allows you to have that functionality without needing to work with the class specificity of the children div's.

JsFiddle: https://jsfiddle.net/9w8zhg7d/7/

Upvotes: 0

Related Questions