0

I have two images, image_0 and image_1, and when each is clicked, I want it to display an alert saying the id of that image. To do this, I have created an array to store these functions (this was necessary because of my previous issue: https://stackoverflow.com/questions/41003122/looping-in-jquery-only-remembers-last-iteration?noredirect=1#comment69215730_41003122).

The code below shows my attempt. However, nothing happens when I click either image. Why?

HTML:

<img id="image_0" src="http://placehold.it/350x150" width="300">
<img id="image_1" src="http://placehold.it/350x150" width="300">

Javascript:

$(document).ready(function()
{
    // The number of images shown
    num_images = 2

    // List of functions for each thumbnail click.
    var image_click_functions = new Array(num_images);

    // Define the function for when the thumbnail is clicked
    function CreateImageClickFunction(image_id)
    {
        return function() { alert(image_id) };
    }

    // Loop through all images, and define the click functions
    for (i = 0; i < num_images; i++)
    {
        image_click_functions[i] = CreateImageClickFunction(i);
        image_id = "#image_" + i;
        $(image_id).click(function()
        {
            image_click_functions[i];
        });
    }
});
1
  • 6
    That's kind of backwards. Have a single click function and pull information from the element clicked. Commented Dec 7, 2016 at 13:48

5 Answers 5

5

Add a common class, create one handler, and use an instance of this

<img class="image" id="image_0" src="http://placehold.it/350x150" width="300">
<img class="image" id="image_1" src="http://placehold.it/350x150" width="300">

JS:

$(".image").click(function() { alert(this.id) });
Sign up to request clarification or add additional context in comments.

1 Comment

The only improvement I would suggest is making it a delegated event handler.
4

Why do you need to write it so complex?

you could very easily do:

$('img').click(function(){
   alert($(this).attr('id'));
}

(this actually creates a different listener for each one)

or you could use on like this:

$(document).on('click','img',function(){
   alert($(this).attr('id'));
})

that has the advantages of:

a. using only one event listener

b. works on dynamically created content (if you add more images using ajax for example, this event listener will still work on the new images)

Comments

1

I think you over-complicate this. Have a look on this example: html:

    $("#container").on("click", "img", function(e){
      console.log($(this).attr("id"));
    })
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container"> 
      <img id="image_0" src="http://placehold.it/350x150" width="300">
      <img id="image_1" src="http://placehold.it/350x150" width="300">
    </div>

example: http://codepen.io/xszaboj/pen/PbeypX?editors=1010

Comments

1

As CreateImageClickFunction(image_id) is returning a function, You just need to pass the function as event handler.

$(image_id).click(image_click_functions[i]);

Alternatively. as per existing HTML you can use Attribute Starts With Selector [name^=”value”] to bind event

$('[id^image_]').click(function(){
    //Extract number from ID
    var idNum = this.id.match(/\d+$/)[0];
})

If you need to store some arbitrary data I would recommend you to use data-* prefixed custom attribute, which can be fetched using $.fn.data() method or HTMLElement.dataset property

<img class="image" data-id="0" src="http://placehold.it/350x150" width="300">
<img class="image" data-id="1" src="http://placehold.it/350x150" width="300">

Script

$(parentContainerSelector).on('click','.image',function(){
   console.log(this.dataset.id);
})

2 Comments

But still a really bad way to do it... single handler and identify item by attributes etc is the way to go
Using the id and the attribute starts with selector is a very obscure way of organizing JS. As a fellow developer, it'd be much more clear to use a dedicated class (e.g. .js-img-click).
0

I think you've overcomplicated by not understanding Closures in your original question. This is a more advanced "feature" in JS, but worth taking time to research and understand.

However, a much simpler way to do this in jQuery, is to use the images as a selector, and iterate over them that way. Then you can access this as the image. Here's example code.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.