2

So I have multiple div's with the same class and inside them images that can be from 1 to 4 depending on the div, I do not know in advance how many images because they come from the database. How can I give the images different classes depending on how many there are in the div. MY html

<section class="feed-section">
    <article class="feed-article">
        <div class="question-options">
            <img src="http://placehold.it/600x400">
        </div>
    </article>
    <article class="feed-article">
        <div class="question-options">
            <img src="http://placehold.it/600x400">
            <img src="http://placehold.it/600x400">
            <img src="http://placehold.it/600x400">
            <img src="http://placehold.it/600x400">
        </div>
    </article>
    <article class="feed-article">
        <div class="question-options">
            <img src="http://placehold.it/600x400">
            <img src="http://placehold.it/600x400">
            <img src="http://placehold.it/600x400">
        </div>
    </article>
</section>

my js

function imagesWidth() {
    var imagesConatiner = $('.question-options').each(function (index) {
        var images = $(this).children('img').length;
        switch (images) {
        case 1:
            $('.question-options img').addClass('one')
            break;
        case 2:
            $('.question-options img').addClass('two')
            break;
        case 3:
            $('.question-options img').addClass('three')
            break;
        case 4:
            $('.question-options img').addClass('four')
            break;
        default:
            console.log(images)
        }
    })
};
imagesWidth()

The problem now is that it ads multiple classes for example to all the images it adds one for three

I want to do them with css like

img.one {
    width:100%
}
img.two {
    width:50%
}

And so on...

Tushar
  • 85,780
  • 21
  • 159
  • 179
user2991920
  • 60
  • 1
  • 7

4 Answers4

2

the problem is the context to what you are adding the class, since you are getting all the question-options container. try this:

function imagesWidth() {
    var imagesConatiner = $('.question-options').each(function (index) {
        var images = $(this).children('img').length;
        var self = $(this);

        switch (images) {
            case 1:
                self.children('img').addClass('one')
                break;
            case 2:
                self.children('img').addClass('two')
                break;
            case 3:
                self.children('img').addClass('three')
                break;
            case 4:
                self.children('img').addClass('four')
                break;
            default:
                console.log(images)
        }
    })
};
imagesWidth()

here is an example fiddle

Overmachine
  • 1,723
  • 3
  • 15
  • 27
1

Your code should be this:

function imagesWidth() {
    var imagesConatiner = $('.question-options').each(function (index) {
        var images = $(this).children('img').length;
        switch (images) {
        case 1:
            $(this).find('img').addClass('one')
            break;
        case 2:
            $(this).find('img').addClass('two')
            break;
        case 3:
            $(this).find('img').addClass('three')
            break;
        case 4:
            $(this).find('img').addClass('four')
            break;
        default:
            console.log(images)
        }
    })
};
imagesWidth()

You were not referencing the parent div as 'this' so was adding classes to all '.question-options' child 'img' tags.

Tushar
  • 85,780
  • 21
  • 159
  • 179
Philip Bevan
  • 347
  • 1
  • 12
0

The problem with your code is that you're using a general selector to add class on images. $('.question-options img') will select all the images inside the element having class question-options. You can use find, children with the current context($(this)) or context selector to select the images which are inside the current element inside the each.

$('img', this).addClass('someclass');

This will add the class to all the img elements which are inside the current element. i.e. .question-options on which iterating.

Your problem will be solved by using any of the above approach.

If you're looking for an flexible and optimized solution,

  1. You can use an array with index as number of images and value as the class
  2. Add the class at the index to all the images

// Create array for the classes, index will be treated as number of images and value is the class to add
// Modify the array according to the maximum number of elements
var classes = ['', 'one', 'two', 'three', 'four'];

function imagesWidth() {
  var imagesConatiner = $('.question-options').each(function(index) {

    // Get the value from the array at the index i.e. no. of images and add it as class to all the images inside this container
    $('img', this).addClass(classes[$(this).children('img').length]);
  })
};
imagesWidth();
img.one {
  width: 100%
}
img.two {
  width: 50%
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.0/jquery.min.js"></script>
<section class="feed-section">
  <article class="feed-article">
    <div class="question-options">
      <img src="http://placehold.it/600x400">
    </div>
  </article>
  <article class="feed-article">
    <div class="question-options">
      <img src="http://placehold.it/600x400">
      <img src="http://placehold.it/600x400">
      <img src="http://placehold.it/600x400">
      <img src="http://placehold.it/600x400">
    </div>
  </article>
  <article class="feed-article">
    <div class="question-options">
      <img src="http://placehold.it/600x400">
      <img src="http://placehold.it/600x400">
      <img src="http://placehold.it/600x400">
    </div>
  </article>
</section>
Tushar
  • 85,780
  • 21
  • 159
  • 179
0

Do you have a specific reason to add specific classes per image? You could achieve the same effect (making sure the images are evenly distributed accross a set width) using pure css flexbox and no javascript.

.question-options {
    display: flex;
    width: 500px;
    flex-direction: row;
    padding: 10px;
    background-color: blue;
}
.question-options div {
    flex: 1 1 auto;
}
.question-options img {
    width: 100%;
}

You will however need to wrap your images in a div to make it work:

<section class="feed-section">
  <article class="feed-article">
    <div class="question-options">
        <div><img src="http://placehold.it/600x400"></div>
    </div>
  </article>
  <article class="feed-article">
    <div class="question-options">
        <div><img src="http://placehold.it/600x400"></div>
        <div><img src="http://placehold.it/600x400"></div>
        <div><img src="http://placehold.it/600x400"></div>
        <div><img src="http://placehold.it/600x400"></div>
    </div>
  </article>
  <article class="feed-article">
    <div class="question-options">
        <div><img src="http://placehold.it/600x400"></div>
        <div><img src="http://placehold.it/600x400"></div>
        <div><img src="http://placehold.it/600x400"></div>
    </div>
  </article>
</section>

Fiddle: https://jsfiddle.net/grxp0gw1/

NB: Flexbox does not (yet) play nice with images. Thanks to this post and this fiddle I was able to make it work.

Community
  • 1
  • 1
wintvelt
  • 13,855
  • 3
  • 38
  • 43
  • (updated answer with links to more help on making this work with css) – wintvelt Oct 02 '15 at 14:27
  • This is not what OP wants, OP want if there are multiple images they should be minimised to show all the images in a container – Tushar Oct 02 '15 at 14:33
  • A Flexbox like solution could do exactly what OP wants. It can make sure that if you have x components (images) they are equally wide and fit exactly in container. Isn't that what OP wants to achieve? – wintvelt Oct 02 '15 at 14:47
  • Yes, but the demo you've added doesn't shows something what OP wants, can you please update the demo – Tushar Oct 02 '15 at 15:03