image click counter event listener issues

1.5k views Asked by At

So I'm creating a "Cat Clicker" for a project in my Udacity course. Basically, we have 5 pictures of cats (I currently have 4), but each cat image should have its own click counter for when the specific image is clicked. I know there's a way to use one for loop, but not sure how. I've been trying to just use an addeventlistener for each individual image, however it's counting every click (no matter where) on the page...can someone figure out what I'm missing/doing wrong?

var sassy = document.createElement("img");
sassy.src = 'images/cat.jpg';
sassy.height = "500";
sassy.width = "640";
sassy.alt = "Sassy Cat";
document.getElementById("catimage").appendChild(sassy);

var addUp = (function() {
  var count = 0;
  return function() {
    var sassy = document.getElementById("catimage");
    if (sassy) sassy.innerHTML = "Picture Clicks: " + ++count;
  }
}());
document.addEventListener("click", addUp, false);

var grumpy = document.createElement("img");
grumpy.src = 'images/grumpy-cat.jpg';
grumpy.height = "500";
grumpy.width = "640";
grumpy.alt = "Grumpy Cat";
document.getElementById("grumpyimage").appendChild(grumpy);

var cuddlecats = document.createElement("img");
cuddlecats.src = 'images/cuddles.jpg';
cuddlecats.height = "500";
cuddlecats.width = "640";
cuddlecats.alt = "Cuddling Cats";
document.getElementById("cuddlingcats").appendChild(cuddlecats);

var sketchy = document.createElement("img");
sketchy.src = 'images/sketchycat.jpg';
sketchy.height = "500";
sketchy.width = "640";
sketchy.alt = "Sketchy Cat";
sketchy.co
document.getElementById("sketchycat").appendChild(sketchy);
<div id="catimage">
  <figcaption>Sassy Cat</figcaption>
  <h3 id="sassycount">Picture Clicks: 0</h3>
</div>

<div id="grumpyimage">
  <figcaption>Grumpy Cat</figcaption>
  <h3 id="grumpycount">Picture Clicks: 0</h3>
</div>
<div id="cuddlingcats">
  <figcaption>Cuddling Cats</figcaption>
  <h3 id="cuddlecount">Picture Clicks: 0</h3>
</div>
<div id="sketchycat">
  <figcaption>Sketchy Cat</figcaption>
  <h3 id="sketchcount">Picture Clicks: 0</h3>
</div>

2

There are 2 answers

1
Emmanuel On BEST ANSWER

The errors you are making are:

  1. You call the addUp function only once: which returns a single instance of your 'inner' function. That inner function has it's closure which contains a single 'count' variable. In other words, you are using only one counter for all the images.
  2. You add the listener to the document. Consequently, anywhere clicked on the document invokes your event listener.

Try this:

var addUp = function(counterId) {
  var count = 0;

  return function () {
     var counterEle = document.getElementById(counterId);
     if (counterEle)
        counterEle.innerHTML = "Picture Clicks: " + ++count;
  }
};

var catImage = document.getElementById("cat-image");
catImage.addEventListener("click", addUp("cat-counter-id"), false);

Repeat the last two lines for the other images.

The important thing to note is that you call addUp to create a listener for each image/counter pair.

There are certainly more efficient ways to achieve the above without using closures, but I gather you're trying to learn closures.

0
sabotero On

Your are adding the event listener to the document, so anywhere you click, image or not, the function addUp is called.

In order to attach an event to a specific element you have to call addEventListener on that element.

var grumpyimage = document.getElementById("grumpyimage");
grumpyimage.addEventListener("click", addUp, false);

Now you can click on the grumpyimage and it will call addUp For simplicity you should have one addUp function for each image.

Keep in mind that you should generalise this for only use one addUp function and increment a counter based on the id of the counter like this:

var addUp = function(counterId) {
  var count = 0;

  return function () {
     var counterEle = document.getElementById(counterId);
     if (counterEle)
        counterEle.innerHTML = "Picture Clicks: " + ++count;
  }
};
var grumpyimage = document.getElementById("grumpyimage");
grumpyimage.addEventListener("click", addUp("grumpyimage-counter"), false);