If one image is open, close the other when clicked

Hi all

I have a number of buttons/images which display another image when clicked. The problem is, I have a number of these images using the same code to function, and if I click them all they’ll all be open.

How do I close one when another is clicked? So no two images will be open/active at the same time.

Reduced for viewing, I have more images.

$( document ).ready(function() {
    $("#kayaking").click(function(){
      imagePath = $("#kayaking").attr("src");
      if(imagePath == "images/kayaking_sml_btn.png"){
          $("#kayaking").attr("src", "images/kayaking_sml_btn_clicked.png");
      }else{
          $("#kayaking").attr("src", "images/kayaking_sml_btn.png");        
      }
    });
    $("#surfing").click(function(){
      imagePath = $("#surfing").attr("src");
      if(imagePath == "images/surfing_sml_btn.png"){
          $("#surfing").attr("src", "images/surfing_sml_btn_clicked.png");
      }else{
          $("#surfing").attr("src", "images/surfing_sml_btn.png");        
      }
    });
    $("#scuba").click(function(){
      imagePath = $("#scuba").attr("src");
      if(imagePath == "images/scuba_sml_btn.png"){
          $("#scuba").attr("src", "images/scuba_sml_btn_clicked.png");
      }else{
          $("#scuba").attr("src", "images/scuba_sml_btn.png");        
      }
    });

Any suggestions?

<img src='images/kayaking_sml_btn.png' class='kayaking btn' id='kayaking'>

Thanks, Barry

Hi Barry,

You have a lot of duplicate code there. Now might be a good time to clean it up.

Could you post a working demo (jsfiddle or similar) demonstrating what you have so far.
I’m sure this won’t be too hard to accomplish.

Thanks Pullo
Slightly reduced the amount of images for viewing.

In an ideal world, I’d really like some sort of slide/toggle effect when the images open and close :smile:

http://jsfiddle.net/y90j5mbp/

I would stick all of the config info in an object literal of some such, then write something more generic:

<img src='beach-seychelles_8881_100x75.jpg' id="one">
<img src='capetown-clifton-beach_8882_100x75.jpg' id="two">
<img src='rasta-galloping_8890_100x75.jpg' id="three">

var imgs = {
  "one": {
    "small": "beach-seychelles_8881_100x75.jpg",
    "big": "beach-seychelles_8881_600x450.jpg"
  },
  "two": {
    "small": "capetown-clifton-beach_8882_100x75.jpg",
    "big": "capetown-clifton-beach_8882_600x450.jpg"
  },
  "three": {
    "small": "rasta-galloping_8890_100x75.jpg",
    "big": "rasta-galloping_8890_600x450.jpg"
  } 
}

function collapseAllImages(){
  $("img").each(function(){
    this.src = imgs[this.id].small;
  });
}

function toggleImage(img){
  if($(img).hasClass("expanded")){
    img.src = imgs[img.id].small;
    $(img).removeClass("expanded").addClass("contracted");
  } else {
    img.src = imgs[img.id].big;
    $(img).removeClass("contracted").addClass("expanded");
  }
}

$("img").click(function(){
  collapseAllImages();
  toggleImage(this);
});

Demo

Perfect!
I’ve just implemented this into my current markup, working good, good work Pullo :smile:

Ok, a couple of small problems, one flourish and a small clicking issue:

  1. I need a second click for the images to respond. Is it possible to make this effect work with one click?
  2. Could we add a little fadeTo() into the mix so the image change has a nice slide, smooth transition?

Thanks, appreciate this really helped me,
Barry

I don’t understand. Is this behaviour in my demo?

Maybe:

$(img).fadeOut('slow', function () {
  img.src = imgs[img.id].big;
  $(img).fadeIn('slow');
});

Yes and no. At first everything works, though once you start clicking different images when other big images are open, you need to click twice.

Example, if we click a small image opening the big image, and then click a different small, this only closes the big image, resulting in a second click to see another big image.

If you open up your fiddle and click a few times you’ll see what I mean.
It doesn’t happen every time, but sometimes it does.

Thanks, Barry

In my fiddle, if I click a small image, its big version opens.
If I then click a different small image then the big image shuts and the second small one expands.
Am I missing something?

In my fiddle, if I click a small image, its big version opens.

Correct, but not everytime. Sometimes if you click another small image, it will only close the current big image and not open the new big image you just clicked. Click a few more times and you’ll see what I mean.

?

Barry

Ah ok, I could reproduce.
It’s late here, so I’m off to bed soon.
Why don’t you try and work out what is happening? You can use your browser’s dev tools to examine which classes are being applied and console.log() to log values to the console.

If you can’t make any headway, let me know and I’ll have a look tomorrow or something.

Cool!
Thanks again Pullo, big push forward for me.

Why don’t you try and work out what is happening?

Will do, though JS not my good language, head goes in a spin when I fire up the console :smile:
I’ll have a go and see if I can fix it.

Sleep well, and thanks.

Barry

I updated my fiddle to remove this error.
I was also able to simplify the code.

var imgs = {
    "one": {
        "small": "beach-seychelles_8881_100x75.jpg",
        "big": "beach-seychelles_8881_600x450.jpg"
    },
    "two": {
        "small": "capetown-clifton-beach_8882_100x75.jpg",
        "big": "capetown-clifton-beach_8882_600x450.jpg"
    },
    "three": {
        "small": "rasta-galloping_8890_100x75.jpg",
        "big": "rasta-galloping_8890_600x450.jpg"
    } 
}

function collapseAllImages(){
  $("img").each(function(){
    this.src = imgs[this.id].small;
  });
}

function expandImage(img){
  img.src = imgs[img.id].big;
}

$("img").click(function(){
  collapseAllImages();
  expandImage(this);
});

Hey Pullo

Fantastic, and thanks for getting back.
I was working on this for quite some time yesterday, trying to add fades etc. trying to understand what was causing the problems.

This is a lot smoother now with one click every time :smile:
The only problem now, we can’t close anything when we click the big image?

Is this something we can add back in?

Thanks,
Barry

Yup.

var imgs = {
    "one": {
        "small": "beach-seychelles_8881_100x75.jpg",
        "big": "beach-seychelles_8881_600x450.jpg"
    },
    "two": {
        "small": "capetown-clifton-beach_8882_100x75.jpg",
        "big": "capetown-clifton-beach_8882_600x450.jpg"
    },
    "three": {
        "small": "rasta-galloping_8890_100x75.jpg",
        "big": "rasta-galloping_8890_600x450.jpg"
    } 
}

function collapseAllImages(){
  $("img").each(function(){
    this.src = imgs[this.id].small;
  });
}

function expandImage(img){
  img.src = imgs[img.id].big;
}

$("img").click(function(){
  var expanded = this.getAttribute("src") === imgs[this.id].big;
  collapseAllImages();
  if (!expanded){
    expandImage(this);
  }
});

New demo

Fantastic Pullo!
This is what we needed :smiley:

Thanks a lot, works brilliant.
I’ll just need to add some effects now, I was adding all the velocityJS effects yesterday trying to animate this. Not sure its needed now running very smooth. Might give it a try.

Appreciate your time. Thank you.
Barry