0

Bear in mind I'm a javascript/jquery/stackoverflow newbie. I have an array of JQuery objects (each one is an image). Right now I've got a separate function for each item in the array:

var $photos = [];
$photos.push($('img.one'), $('img.two'), $('img.three'), $('img.four'), $('img.five'),              $('img.six'));
$('.thumbnails img.two').click(function(){
    $('div#slide-container').fadeIn('fast');
    setTimeout(function(){
    $('div#slideshow').slideDown('fast');}, 200);
    setTimeout(function(){
    images[1].fadeIn('fast');}, 500);
});

In other words I have the above code for each of the 5 indexes in the array. How can I write this so that I can target whichever photo is clicked using just one function instead of six? So instead of "images[1]" specifically, I can just say "images[i]".

Here's a link to a live version of this:

http://www.noticeeverything.com/photos/

Justin
  • 1,341
  • 11
  • 24
  • I guess I'm asking if there's something more generic I can use. Something like this, only that actually works: $photos[i].click(function(){ $(this).fadeIn(); }); – Justin Dec 27 '13 at 22:53

3 Answers3

1

You can write a general click handler for all the images that uses $(this) to refer to the element clicked on. To make it available in the setTimeout callback, you'll need to set a local variable to it, so it will be saved in the closure.

$(".thumbnails img").click(function() {
    var $this = $(this);
    $('div#slide-container').fadeIn('fast');
    setTimeout(function() {
        $('div#slideshow').slideDown('fast');
    }, 200);
    setTimeout(function() {
        $this.fadeIn('fast');
    }, 500);
});

UPDATE:

There's no need for the array. This version just assumes that the images in the slideshow are in the same position as the TDs containing the corresponding thumbnails, and uses .eq() to find them.

$("#thumbnails img.thumb").click(function () {
    var index = $(this).closest('td').index();
    $('div#slide-container').fadeIn('fast');
    setTimeout(function () {
        $('div#slideshow').slideDown('fast');
    }, 200);
    setTimeout(function () {
        $("div#slideshow img").eq(index).fadeIn('fast');
    }, 500);
});

DEMO

The reason $(this) wasn't being set earlier is because you had .thumbnails, and I copied that, but it should be #thumbnails. So the selector wasn't matching the elements.

Barmar
  • 741,623
  • 53
  • 500
  • 612
  • Thanks so much for the responses. Is there a way to set the var $this equal to the index in my array to which it corresponds? For whatever reason, jQuery is not recognizing $(this) as the specific image clicked and so no image is being shown until I click my 'next' button. – Justin Dec 27 '13 at 23:04
  • `$(this)` should be recognized, and we'd need to use it to find the array index anyway. Can you make a jsfiddle with your HTML, so we can try to figure out why it's not working? – Barmar Dec 27 '13 at 23:07
  • It took me a bit because I had no idea what a jsfiddle was. Here's the link http://jsfiddle.net/scptM/ – Justin Dec 27 '13 at 23:17
  • And the full screen (much more helpful for viewing):http://jsfiddle.net/scptM/embedded/result/ – Justin Dec 27 '13 at 23:19
  • As you can see, no image is being loaded with the div#slideshow. You don't get an image until you click 'next'. – Justin Dec 27 '13 at 23:20
  • I'm sorry, I totally misunderstood what you were doing. I thought the images in the array were the thumbnails being clicked on. – Barmar Dec 27 '13 at 23:24
  • I'll get you a new solution in a few minutes – Barmar Dec 27 '13 at 23:24
  • @Barmar: Thanks a ton! Just to make sure I understand what you did: the value of the local variable is equal to the index of the closest td element to img.thumb, and the eq() method is calling that index position and whatever is living there? – Justin Dec 28 '13 at 01:23
  • Right. `eq` is essentially treating the list of slideshow images as an array, and accessing the corresponding element of the array. – Barmar Dec 28 '13 at 01:27
  • @Barmar: Again, thanks. And not to hog your good will here, but do you have any idea why there's an empty frame when you click backward from one to six, but not when you click forward from six to one? – Justin Dec 28 '13 at 01:50
  • When `$curr` is the first image, `$curr.prev()` is ` – Barmar Dec 28 '13 at 01:53
  • Use `$curr.prev('img')` to test if you're at the first image. – Barmar Dec 28 '13 at 01:54
  • And instead of giving them classes `one`, `two`, etc. Use `$("#slideshow img:first")` and `$("#slideshow img:last")` to wrap around. – Barmar Dec 28 '13 at 01:55
  • @Barmar: Thank you! This is such a great community. I guess I'll pay it forward by doing the same for someone else when I actually learn this stuff :) – Justin Dec 28 '13 at 02:15
1
$('.thumbnails img').click(function(){
    var $this = $(this);
    $('div#slide-container').fadeIn('fast');
    setTimeout(function(){
    $('div#slideshow').slideDown('fast');}, 200);
    setTimeout(function(){
    $this.fadeIn('fast');}, 500); });

Also I think you can use callback instead of setTimeout

$('.thumbnails img').click(function(){
    var $this = $(this);
    $('div#slide-container').fadeIn('fast', function(){
        $('div#slideshow').slideDown('fast', function(){
            $this.fadeIn('fast');
        });
    });
});
standup75
  • 4,734
  • 6
  • 28
  • 49
  • +1 for the second version, I was about to suggest something like that in my answer. – Barmar Dec 27 '13 at 22:50
  • So a callback is a nested function which accomplishes firing events sequentially instead of all at once? – Justin Dec 27 '13 at 23:08
  • A callback is a function that is called asynchronously, in this case jQuery is calling them when the function (fadeIn or slideDown) is complete – standup75 Dec 27 '13 at 23:11
0

You can use jQuery selectors. In this case, you will use the 'ancestor descendant' (http://api.jquery.com/descendant-selector/) - Selects all elements that are descendants of a given ancestor.

This:

// Everything inside `.thumbnails` with tag `img`
$('.thumbnails img')

HTML (example)

<ul class="thumbnails">
  <li><img src="..."></li>
  <li><img src="..."></li> 
  <li><img src="..."></li>
  <li><img src="..."></li>
</ul>

jQuery

(function($){
  $('.thumbnails img').on('click',function(e){
     e.preventDefault();
     // do someting...
  });
})(jQuery);
Eduardo Stuart
  • 2,869
  • 18
  • 22