4

I have an image, and on top of that image is another smaller image. When the first image is clicked, the second one appears, and it disappears when the first image is clicked again. My problem is when the second image appears over the first one, it makes the area that it covers of the first image unclickable. Is it possible to make it so the first image can be clicked through the second image?

This is the HTML for the second image (it's generated in PHP):

Echo '<img src="images/tick.png" id="tick' . $i .'" class="hidden" style="position: absolute; top: 0px; left: 70%;"/>';
MitchCool1
  • 329
  • 3
  • 14
  • Is the image supposed to come on top of another image? – Praveen Kumar Purushothaman Jun 09 '15 at 07:55
  • where is your JavaScript? Why you don't use bubbling? – smnbbrv Jun 09 '15 at 07:58
  • 1
    Hello, just a question : if your 2nd image overlaps the first one, isn't it simpler to click on the second image to make it disappear ? So the behaviour would be : 1st image click -> make 2nd appears, 2nd image click -> make it disappears. Then you'll have a natural go and back UI. A quick piece of code on your php : `Echo '';` – user1713964 Jun 09 '15 at 07:58
  • Simply put both images in a container, and attach the click event handler to that instead of the bigger image. This way you can simply make use of event bubbling (which isn't possible on an image since it cannot have child elements). – connexo Jun 09 '15 at 08:00
  • You are looking for `pointer-events`, but be aware that you are also indirectly trying to implement what is known as "click-jacking", which most browsers will implement some protection against and thus you may not get the results you want consistently (and this is good, since having a user click on one image but actually clicking on another hiding underneath is *really* bad). https://www.owasp.org/index.php/Clickjacking – Anthony Jun 09 '15 at 08:02
  • 1
    @simon He's probably not using bubbling because I assume his click event is tied to the bigger image, so bubbling in this case cannot work as the bigger image cannot act as a parent element of the smaller image. – connexo Jun 09 '15 at 08:03
  • @connexo, you are fully right, thanks for pointing – smnbbrv Jun 09 '15 at 08:05

3 Answers3

3

Simply put both images in a container div, and attach the click event handler to that instead of the bigger image. This way you can simply make use of event bubbling (which isn't available on the bigger image since it cannot have child elements, such as the smaller image).

Find a working solution here:

https://jsfiddle.net/6nnwy3xw/

$(document).ready(function() {
    $('.imgcontainer').on('click', function() {
        $(this).toggleClass('toggleImg');
    });
})
.imgcontainer {
    height: 300px;
    width: 300px;
    position: relative;
}

.imgcontainer img:first-child {
    display: block;
    height: 300px;
    width: 300px;
}

.imgcontainer img+img {
    position: absolute;
    top: 50px;
    left: 50px;
    opacity: 0;
    transition-duration: 0.3s;
}

.imgcontainer.toggleImg img+img {
    opacity: 1;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="imgcontainer">
    <img src="http://lorempixel.com/300/300" />
    <img src="http://lorempixel.com/200/200" />
</div>

I'm assuming your use-case is some kind of checkbox replacement element? In this case, this may also be of interest to you:

Use images like checkboxes

If that is the case, I'd make the surrounding diva label instead, so it also automatically checks your (probably hidden) real checkbox.

Community
  • 1
  • 1
connexo
  • 53,704
  • 14
  • 91
  • 128
2

If I understand the issue you're describing properly, you could try turning pointer-events off for the second image, that is often displayed over the click-target:

.two { pointer-events: none; }

Note that this is only supported with HTML in Internet Explorer 11 and up (as well as in Chrome and Firefox). For SVG, support was available in IE 9. That may suffice for a work-around if needed.

Fiddle: http://jsfiddle.net/tbqxjp19/

For better support you should move your handler to an element that will not be obstructed, and as such will always work to toggle the visibility of the second image:

<div class="images">
    <img src="http://placehold.it/100x100" class="one" />
    <img src="http://placehold.it/100x100/000000" class="two" />
</div>
document.querySelector( ".images" ).addEventListener( "click", function () {
    this.classList.toggle( "toggled" );
});

The above simply binds a handler to click events on the .images container, toggling a class that will hide and/or reveal the second image, given the following:

.toggled .two {
    opacity: .1;
}

Fiddle: http://jsfiddle.net/tbqxjp19/1/

Sampson
  • 265,109
  • 74
  • 539
  • 565
  • Good answer - despite it's just what I answered 6 minutes before you, replacing jQuery by vanilla JS. Some credit would have been nice. – connexo Jun 09 '15 at 08:40
  • Sorry? Look at the edit histories. I provided my code before you did yours. Regardless, it's not a contest :) – Sampson Jun 09 '15 at 08:45
  • And you're sure it wasn't triggered by my comment on the question itself? Just asking. – connexo Jun 09 '15 at 08:48
  • @connexo Upvoted your answer. Nothing was copied from you. Your answer is also good, so enjoy an upvote ;) – Sampson Jun 09 '15 at 08:53
  • If you'd put a little more effort into explaining the `pointer-events` part of your answer, I would have probably upvoted yours as well :) – connexo Jun 09 '15 at 09:00
0

Try this , if you are fine with jquery solution.

HTML

<img src="images/large.png" class ="image" id="image1" style="position: absolute; top: 0px; left: 0px;" />
<img src="images/small.png" id="image2" class ="image" style="position: absolute; top: 0px; left: 0px; z-index:10;" />

css

.hiddenimage{
 display:none;
}

JQuery

$(".image").click(function(){
  ("#image2").toggleClass("hiddenimage");
})
Tuhin
  • 3,335
  • 2
  • 16
  • 27