# "Image gallery" assessment

**URL:** <https://discourse.mozilla.org/t/image-gallery-assessment/24687>\
**Category:** Learn\
**Created:** [July 14, 2017, 9:52am UTC](https://discourse.mozilla.org/t/image-gallery-assessment/24687 "2017-07-14T09:52:48Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![Steve\_Davis](https://avatars.discourse-cdn.com/v4/letter/s/bcef8e/32.png) [@Steve\_Davis](https://discourse.mozilla.org/u/Steve_Davis)\
**Post date:** [July 14, 2017, 9:52am UTC](https://discourse.mozilla.org/t/image-gallery-assessment/24687/1 "2017-07-14T09:52:48Z")

</div>

Hi there! I have been working my way through the JavaScript course over the last few weeks I started from the very beginning and have just about finished the first part. I have just finished the image gallery assessment that contains a css, js and html files and I want someone to take a look over my work and let me know how I’ve done. Can you tell me what I need to do please.

Thanks  
Steve

---

<div class="post-metadata">

**Author:** ![chrisdavidmills](https://sea1.discourse-cdn.com/flex001/user_avatar/discourse.mozilla.org/chrisdavidmills/32/21688_2.png) [@chrisdavidmills](https://discourse.mozilla.org/u/chrisdavidmills)\
**Post date:** [July 17, 2017, 9:43am UTC](https://discourse.mozilla.org/t/image-gallery-assessment/24687/2 "2017-07-17T09:43:26Z")

</div>

> Hi there! I have been working my way through the JavaScript course over the last few weeks I started from the very beginning and have just about finished the first part. I have just finished the image gallery assessment that contains a css, js and html files and I want someone to take a look over my work and let me know how I’ve done. Can you tell me what I need to do please.

Hi Steve,

Nice work! You can find the finished image gallery example here (go through and see if your code matches up):

> **[learning-area/javascript/building-blocks/gallery at main · mdn/learning-area](https://github.com/mdn/learning-area/tree/main/javascript/building-blocks/gallery)**
>
> GitHub repo for the MDN Learning Area. . Contribute to mdn/learning-area development by creating an account on GitHub.

The directory also contains the marking guide for this assessment, which tells you exactly what you need to do to score full marks:

> <https://github.com/mdn/learning-area/blob/main/javascript/building-blocks/gallery/marking-guide.md>

Don’t hesitate to ask if you have more questions.

---

<div class="post-metadata">

**Author:** ![Steve\_Davis](https://avatars.discourse-cdn.com/v4/letter/s/bcef8e/32.png) [@Steve\_Davis](https://discourse.mozilla.org/u/Steve_Davis)\
**Post date:** [July 17, 2017, 2:39pm UTC](https://discourse.mozilla.org/t/image-gallery-assessment/24687/3 "2017-07-17T14:39:02Z")

</div>

Hi Chris firstly thanks for your reply.

I was hoping not to self mark really this would help me get a proper unbiased assessment grade. I’m sure you understand when your working on your own as I have been it’s easy to con yourself that your work meets the grade…

However I have to say on this occasion I feel as though I’m pretty close the only real difference is that I have used an array to hold all the photo path values. But to me this is better than making up the path in the loop because you don’t have to change the code to change the photo - just substitute or add to the array, I have set the loop using the array.length property anyway. I think the rest is the same looking at what is required in the marking guide. What do you think.\* \*

---

<div class="post-metadata">

**Author:** ![chrisdavidmills](https://sea1.discourse-cdn.com/flex001/user_avatar/discourse.mozilla.org/chrisdavidmills/32/21688_2.png) [@chrisdavidmills](https://discourse.mozilla.org/u/chrisdavidmills)\
**Post date:** [July 17, 2017, 3:05pm UTC](https://discourse.mozilla.org/t/image-gallery-assessment/24687/4 "2017-07-17T15:05:03Z")

</div>

> I was hoping not to self mark really this would help me get a proper unbiased assessment grade. I’m sure you understand when your working on your own as I have been it’s easy to con yourself that your work meets the grade…

I agree with you. However, unfortunately we haven’t got the resources to manually assess everyone’s entries. I wish we did.

> However I have to say on this occasion I feel as though I’m pretty close the only real difference is that I have used an array to hold all the photo path values. But to me this is better than making up the path in the loop because you don’t have to change the code to change the photo - just substitute or add to the array, I have set the loop using the array.length property anyway. I think the rest is the same looking at what is required in the marking guide. What do you think.\* \*

Yeah, cool, that all sounds fine. I agree that the array is a better way of doing this. In a real app, you’d probably retrieve the photos and info via some kind of JSON structure via an XHR call, or similar.

---

<div class="post-metadata">

**Author:** ![juandesouza](https://avatars.discourse-cdn.com/v4/letter/j/71e660/32.png) [@juandesouza](https://discourse.mozilla.org/u/juandesouza)\
**Post date:** [November 3, 2017, 2:17am UTC](https://discourse.mozilla.org/t/image-gallery-assessment/24687/5 "2017-11-03T02:17:42Z")

</div>

Hi everyone! I’m stuck in the Image Gallery assessment. Can anyone show me the code? It’s really annoying that they do not show the code on the page!

> **[Image gallery](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Building_blocks/Image_gallery)**
>
> Now that we've looked at the fundamental building blocks of JavaScript, we'll test your knowledge of loops, functions, conditionals and events by getting you to build a fairly common item you'll see on a lot of websites — a JavaScript-powered image...

---

<div class="post-metadata">

**Author:** ![chrisdavidmills](https://sea1.discourse-cdn.com/flex001/user_avatar/discourse.mozilla.org/chrisdavidmills/32/21688_2.png) [@chrisdavidmills](https://discourse.mozilla.org/u/chrisdavidmills)\
**Post date:** [November 3, 2017, 7:05am UTC](https://discourse.mozilla.org/t/image-gallery-assessment/24687/6 "2017-11-03T07:05:06Z")

</div>

> [@Learning web development: Marking guides and questions](https://discourse.mozilla.org/t/learning-web-development-marking-guides-and-questions/16294/148):
>
> Hi everyone! I’m stuck in the Image Gallery assessment. Can anyone show me the code? It’s really annoying that they do not show the code on the page!

You can find the finished code here:

> **[learning-area/javascript/building-blocks/gallery at main · mdn/learning-area](https://github.com/mdn/learning-area/tree/main/javascript/building-blocks/gallery)**
>
> GitHub repo for the MDN Learning Area. . Contribute to mdn/learning-area development by creating an account on GitHub.

---

<div class="post-metadata">

**Author:** ![Paul\_Harris](https://avatars.discourse-cdn.com/v4/letter/p/f1d935/32.png) [@Paul\_Harris](https://discourse.mozilla.org/u/Paul_Harris)\
**Post date:** [October 6, 2017, 12:20pm UTC](https://discourse.mozilla.org/t/image-gallery-assessment/24687/7 "2017-10-06T12:20:13Z")

</div>

I have a question about the adding an onclick handler in [https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Building\_blocks/Image\_gallery](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Building_blocks/Image_gallery) section

[https://pastebin.mozilla.org/9069371](https://pastebin.mozilla.org/9069371) this is what I have so far

I’m confused as to how I get the “src” without using newImage as the event object won’t contain the information either if i set the event object to bbb it’s still the same thing as using newImage

---

<div class="post-metadata">

**Author:** ![2alin](https://sea1.discourse-cdn.com/flex001/user_avatar/discourse.mozilla.org/2alin/32/49543_2.png) [@2alin](https://discourse.mozilla.org/u/2alin)\
**Post date:** [March 8, 2018, 6:07am UTC](https://discourse.mozilla.org/t/image-gallery-assessment/24687/8 "2018-03-08T06:07:54Z")

</div>

@Paul_Harris Unfortunately your code is no longer available, so I can’t see what you had made. In the guidelines, think Chris gave us a hint with “event” and “target” and suggested us to use [Event objects](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Building_blocks/Events#Event_objects) as is explained in the course, or at least that’s what I used (haven’t checked the solved code).

---

<div class="post-metadata">

**Author:** ![2alin](https://sea1.discourse-cdn.com/flex001/user_avatar/discourse.mozilla.org/2alin/32/49543_2.png) [@2alin](https://discourse.mozilla.org/u/2alin)\
**Post date:** [March 8, 2018, 6:55am UTC](https://discourse.mozilla.org/t/image-gallery-assessment/24687/9 "2018-03-08T06:55:57Z")

</div>

And this is my [JS code](https://github.com/2alin/2alin.github.io/blob/master/learn/mozilla/image-gallery/main.js) and [live preview](https://2alin.github.io/learn/mozilla/image-gallery/index.html) . Only points to highlight in my code comparing to the solved one by chris are:

1. I used `addEventListener` instead of using the event handler as property. Being able to remove the listeners was what made me decide for it (even if it didn’t matter at this early stage 😅).
2. Because of the previous point, I didn’t code the `displayImage` function specified in the guidelines. It was going to be only one line in there, and I was already using event function handlers. Too many functions for something that simple. But, I was able to see that setting up `displayImage` allow us to used it in a wide different set of events in case we want to improve our gallery; i.e. dragging a file to the page, display such picture and show another thumbnail at the bottom.

I loved this assessment! it was challenging. I’m going to read again the “Introduction to events” section as well as the external links in there. I felt like it was a stepped curve of learning.

---

<div class="post-metadata">

**Author:** ![patty518](https://avatars.discourse-cdn.com/v4/letter/p/71c47a/32.png) [@patty518](https://discourse.mozilla.org/u/patty518)\
**Post date:** [April 30, 2018, 10:18pm UTC](https://discourse.mozilla.org/t/image-gallery-assessment/24687/10 "2018-04-30T22:18:34Z")

</div>

Hello!

my code is the following:

for( i=1; i\<=5; i++) {  
var newImage = document.createElement(‘img’);  
newImage.setAttribute(‘src’, ‘images/pic’ + i + ‘.jpg’);

function whatever(e) {  
displayedImage.setAttribute(‘src’, e.target.getAttribute(‘src’));  
}

newImage.addEventListener(‘click’, whatever);  
thumbBar.appendChild(newImage);  
}

It seems to be working. My questions are the following:

1. is there a preference for having the function ‘whatever’ inside the for loop or outside the for loop? mine is within the loop, but the solution code places it outside. Just want to know if there are any cases, and if so, what they are, in which one would be preferable.

2. does the placement for the line ‘thumbBar.appendChild(newImage);’ matter, or can it be placed anywhere inside the for loop?

3. I see that in the solution code, the function displayImage(imgSrc) is called before the function is defined, but I was under the impression that the code would crash if a function is called before it’s defined. can you please clarify the order of function calling and definition?

And finally, just want to say that i found this assessment to be challenging and fun!

---

<div class="post-metadata">

**Author:** ![chrisdavidmills](https://sea1.discourse-cdn.com/flex001/user_avatar/discourse.mozilla.org/chrisdavidmills/32/21688_2.png) [@chrisdavidmills](https://discourse.mozilla.org/u/chrisdavidmills)\
**Post date:** [May 1, 2018, 11:58am UTC](https://discourse.mozilla.org/t/image-gallery-assessment/24687/11 "2018-05-01T11:58:12Z")

</div>

Hi there Patty,

Thanks for sharing your solution. I had a bit of a play, and ended up with this:

```auto
/* Looping through images */

function displayImage(e) {
  displayedImage.setAttribute('src', e.target.getAttribute('src'));
}

for(var i = 1; i <= 5; i++) {
  var newImage = document.createElement('img');
  newImage.setAttribute('src', 'images/pic' + i + '.jpg');
  thumbBar.appendChild(newImage);
  newImage.addEventListener('click', displayImage);
}

```

I think that if anything this is a better solution than our final example, although obviously I’ve got the function outside the solution. But you’ve improved on it by adding an event listener, rather than using an onclick handler function. Again, removing a function from the loop.

It is generally considered bad practice to include a function inside a loop, as it can cause problems in some circumstances. It is better to define the function outside the loop and reference it from inside.

I am going to update our example when I get the time to use something more like this. I’ve made a note of it. Thanks again for jogging me on this!

To answer your questions:

1. See above.
2. There is flexibility here, but it does need to be placed after you have defined newImage, otherwise you’ll get an undefined error.
3. the answer here is “it depends” — this stack overflow post provides useful reading on bthe matter: [https://stackoverflow.com/questions/9973461/does-a-javascript-function-have-to-be-defined-before-calling-it](https://stackoverflow.com/questions/9973461/does-a-javascript-function-have-to-be-defined-before-calling-it)

---

<div class="post-metadata">

**Author:** ![mattia.lorenz](https://avatars.discourse-cdn.com/v4/letter/m/3ab097/32.png) [@mattia.lorenz](https://discourse.mozilla.org/u/mattia.lorenz)\
**Post date:** [June 2, 2018, 9:15pm UTC](https://discourse.mozilla.org/t/image-gallery-assessment/24687/12 "2018-06-02T21:15:30Z")

</div>

Hi guys,

this is my code and it’s currently working. What do you think?

/\* Looping through images \*/  
for (i = 1; i \<= 5; i++) {  
var newImage = document.createElement(‘img’);  
newImage.setAttribute(‘src’, ‘./images/pic’ + i + ‘.jpg’);  
thumbBar.appendChild(newImage);  
newImage.onclick = getTheImage;  
function getTheImage(e, src) {  
var src = e.target.getAttribute(‘src’);  
displayedImage.setAttribute(‘src’, src);  
};  
};

/\* Wiring up the Darken/Lighten button \*/  
btn.onclick = changeOverlay;  
function changeOverlay () {  
var cl = btn.getAttribute(‘class’);  
if (cl === ‘dark’) {  
btn.setAttribute(‘class’, ‘light’);  
btn.textContent = ‘Lighten’;  
overlay.style.backgroundColor = ‘rgba(0,0,0,0.5)’;  
}  
else {  
btn.setAttribute(‘class’, ‘dark’);  
btn.textContent = ‘Darken’;  
overlay.style.backgroundColor = ‘rgba(0,0,0,0)’;  
}  
};

---

<div class="post-metadata">

**Author:** ![chrisdavidmills](https://sea1.discourse-cdn.com/flex001/user_avatar/discourse.mozilla.org/chrisdavidmills/32/21688_2.png) [@chrisdavidmills](https://discourse.mozilla.org/u/chrisdavidmills)\
**Post date:** [June 4, 2018, 5:43am UTC](https://discourse.mozilla.org/t/image-gallery-assessment/24687/13 "2018-06-04T05:43:53Z")

</div>

Hi Mattia,

Your code doesn’t look too at at all — nice job!

One bit of feedback I can give you — in the following block:

```auto
function getTheImage(e, src) {
var src = e.target.getAttribute('src');
displayedImage.setAttribute('src', src);
}
}

```

You don’t need to define the `src` parameter in the function, as you are getting `src` inside the function body in the second line instead. So the following would work fine:

```auto
function getTheImage(e) {
var src = e.target.getAttribute('src');
displayedImage.setAttribute('src', src);
}
}

```

---

<div class="post-metadata">

**Author:** ![AvidLearner](https://avatars.discourse-cdn.com/v4/letter/a/2bfe46/32.png) [@AvidLearner](https://discourse.mozilla.org/u/AvidLearner)\
**Post date:** [July 20, 2018, 5:41am UTC](https://discourse.mozilla.org/t/image-gallery-assessment/24687/14 "2018-07-20T05:41:32Z")

</div>

> **Problem**
>
> Hello, I have a problem here. I don’t understand what didn’t work in my function that tries to change the source of `displayedImage`. My code:
> 
> ```
> var displayedImage = document.querySelector('.displayed-img');
> var thumbBar = document.querySelector('.thumb-bar');
> 
> btn = document.querySelector('button');
> var overlay = document.querySelector('.overlay');
> 
> for (var i = 0; i < 5; i++) {
> var newImage = document.createElement('img');
> var path = 'images/pic' + (i + 1).toString() + '.jpg';
> newImage.setAttribute('src', path);
> thumbBar.appendChild(newImage);
> }
> 
> var image = document.getElementsByTagName('img');
> 
> function sourceAlter(e) {
> var source = e.target.getAttribute('src');
> displayedImage.setAttribute('src', source);
> }
> 
> image.onclick = sourceAlter;
> 
> ```
> 
> Furthermore, when I tried to change `image.onclick = sourceAlter;` to `image.addEventListener('click', sourceAlter)`, the console says that `image.addEventListener` is not a function. Why is that so?

**EDIT:**  
I’ve found out the problem to my code. Apparently, `getElementsByTagName` returns and array and therefore, I have to access the array items one by one. This also caused problems when I tried to pass `image` directly to `addEventListener`. I’ve fixed my code to the following, please grade me 🙂 :

```
var displayedImage = document.querySelector('.displayed-img');
var thumbBar = document.querySelector('.thumb-bar');

btn = document.querySelector('button');
var overlay = document.querySelector('.overlay');

for (var i = 0; i < 5; i++) {
  var newImage = document.createElement('img');
  var path = 'images/pic' + (i + 1).toString() + '.jpg';
  newImage.setAttribute('src', path);
  thumbBar.appendChild(newImage);
}

var image = document.getElementsByTagName('img');

function sourceAlter(e) {
	var source = e.target.getAttribute('src');
	displayedImage.setAttribute('src', source);
}

for (var i = 0; i < image.length; i++) {
	image[i].addEventListener('click', sourceAlter);
}

/* Wiring up the Darken/Lighten button */
btn.onclick = function() {
	if (btn.getAttribute('class') === 'dark') {
		btn.setAttribute('class', 'light');
		btn.textContent = 'Lighten';
		overlay.style.backgroundColor = 'rgba(0, 0, 0, 0.5)';
	}

	else {
		btn.setAttribute('class', 'dark');
		btn.textContent = 'Darken';
		overlay.style.backgroundColor = 'rgba(0, 0, 0, 0)';
	}
}
```

---

<div class="post-metadata">

**Author:** ![chrisdavidmills](https://sea1.discourse-cdn.com/flex001/user_avatar/discourse.mozilla.org/chrisdavidmills/32/21688_2.png) [@chrisdavidmills](https://discourse.mozilla.org/u/chrisdavidmills)\
**Post date:** [July 20, 2018, 8:54am UTC](https://discourse.mozilla.org/t/image-gallery-assessment/24687/15 "2018-07-20T08:54:12Z")

</div>

Hi @AvidLearner, congratulations on sorting your problem out! Pretty much all of the ways of return multiple element references will return an array that you need to loop through (whether it is getElementsByTagName, getElementsByName, or the more modern querySelectorAll).

I don’t tend to give you an exact grade, as I just don’t have time to mark all the assessment entries in detail. What I can do is test your code (it is a little different to mine, but it works fine, well done), and give you links to the marking guide and finished code so you can check it yourself:

- Marking guide: [https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/gallery/marking-guide.md](https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/gallery/marking-guide.md)
- Live example: [https://mdn.github.io/learning-area/javascript/building-blocks/gallery/](https://mdn.github.io/learning-area/javascript/building-blocks/gallery/)
- Source code: [https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/gallery/main.js](https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/gallery/main.js)

---

<div class="post-metadata">

**Author:** ![AvidLearner](https://avatars.discourse-cdn.com/v4/letter/a/2bfe46/32.png) [@AvidLearner](https://discourse.mozilla.org/u/AvidLearner)\
**Post date:** [July 20, 2018, 12:14pm UTC](https://discourse.mozilla.org/t/image-gallery-assessment/24687/16 "2018-07-20T12:14:25Z")

</div>

@chrisdavidmills I have some questions, though, if you don’t mind me asking.

1. Here, my function `sourceAlter` only has the parameter `e` and therefore, I did not pass any parameters when I called the function, hence `image[i].addEventListener('click', sourceAlter)` without any parentheses and parameters. However, what if my function requires two parameters, e.g. `sourceAlter(a, b)`, how do I pass on the parameters to said function?

2. I don’t quite understand how looping works in JavaScript. It somehow does not make sense to me how `for (...)` in my code above worked. I do know that it loops five times (as expressed in the conditional statement `i < image.length`) and that whenever an `image` with the order `i` is clicked, we run a function. But, when we click picture 1, 2,3 and then 1 again, it somehow worked? There is not decrement in the `for` loop, so how did it happen? Is the loop run over again after each action (in this case, click (but doesn’t have to be necessarily a click))?

---

<div class="post-metadata">

**Author:** ![chrisdavidmills](https://sea1.discourse-cdn.com/flex001/user_avatar/discourse.mozilla.org/chrisdavidmills/32/21688_2.png) [@chrisdavidmills](https://discourse.mozilla.org/u/chrisdavidmills)\
**Post date:** [July 23, 2018, 10:13am UTC](https://discourse.mozilla.org/t/image-gallery-assessment/24687/17 "2018-07-23T10:13:09Z")

</div>

> [@AvidLearner](#):
>
> - Here, my function `sourceAlter` only has the parameter `e` and therefore, I did not pass any parameters when I called the function, hence `image[i].addEventListener('click', sourceAlter)` without any parentheses and parameters. However, what if my function requires two parameters, e.g. `sourceAlter(a, b)` , how do I pass on the parameters to said function?
> 
> - I don’t quite understand how looping works in JavaScript. It somehow does not make sense to me how `for (...)` in my code above worked. I do know that it loops five times (as expressed in the conditional statement `i < image.length` ) and that whenever an `image` with the order `i` is clicked, we run a function. But, when we click picture 1, 2,3 and then 1 again, it somehow worked? There is not decrement in the `for` loop, so how did it happen? Is the loop run over again after each action (in this case, click (but doesn’t have to be necessarily a click))?

So to answer the first question, this isn’t the simplest, but it is possible. This stack overflow answer is useful, and contains multiple ways of doing it: [javascript - How to pass arguments to addEventListener listener function? - Stack Overflow](https://stackoverflow.com/questions/256754/how-to-pass-arguments-to-addeventlistener-listener-function)

For the second question, the loop only runs once. But one of the main things the loop does is to add an onclick handler to each image, using this code:

```auto
newImage.onclick = function(e) {
    var imgSrc = e.target.getAttribute('src');
    displayImage(imgSrc);
}

```

because that handler is added to each image, it is run every time an image is clicked.

---

<div class="post-metadata">

**Author:** ![impresently](https://avatars.discourse-cdn.com/v4/letter/i/85e7bf/32.png) [@impresently](https://discourse.mozilla.org/u/impresently)\
**Post date:** [July 25, 2018, 2:26pm UTC](https://discourse.mozilla.org/t/image-gallery-assessment/24687/18 "2018-07-25T14:26:01Z")

</div>

I’m a little confused on how event objects work.

In my for loop the following code works:

```
for (i = 1; i <= 5; i++) {
    var newImage = document.createElement('img');
    newImage.setAttribute('src', "images\/pic" + i + ".jpg");
    thumbBar.appendChild(newImage);
    function displayThumb(clickedImage) {
        var imageThumb = clickedImage.target.getAttribute('src');
        displayedImage.setAttribute('src', imageThumb);
    };
    newImage.addEventListener('click', displayThumb);
}

```

While the following does not work:

```
for (i = 1; i <= 5; i++) {
    var newImage = document.createElement('img');
    newImage.setAttribute('src', "images\/pic" + i + ".jpg");
    thumbBar.appendChild(newImage);
    function displayThumb(clickedImage) {
        var imageThumb = newImage.getAttribute('src');
        displayedImage.setAttribute('src', imageThumb);
    };
    newImage.addEventListener('click', displayThumb);
}

```

In other words, what is the event object in the displayThumb function doing in the first example that allows it to be functioning on the entire loop, whereas in the second example the loop is completed, and the click events only function on the last thumbnail.

---

<div class="post-metadata">

**Author:** ![Mittineague](https://sea1.discourse-cdn.com/flex001/user_avatar/discourse.mozilla.org/mittineague/32/23743_2.png) [@Mittineague](https://discourse.mozilla.org/u/Mittineague)\
**Post date:** [July 25, 2018, 3:22pm UTC](https://discourse.mozilla.org/t/image-gallery-assessment/24687/19 "2018-07-25T15:22:20Z")

</div>

> [@impresently](#):
>
> a little confused

I know how you feel, I’m not new to JavaScript and I don’t understand it well enough to easily explain it, but it has to do with “closures” and “lexical scope”

I think the “Creating closures in loops: A common mistake” section near the end of this page does the best job at explaining that I’ve seen.

> **[Closures - JavaScript | MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures)**
>
> A closure is the combination of a function bundled together (enclosed) with references to its surrounding state (the lexical environment). In other words, a closure gives a function access to its outer scope. In JavaScript, closures are created every...

---

<div class="post-metadata">

**Author:** ![chrisdavidmills](https://sea1.discourse-cdn.com/flex001/user_avatar/discourse.mozilla.org/chrisdavidmills/32/21688_2.png) [@chrisdavidmills](https://discourse.mozilla.org/u/chrisdavidmills)\
**Post date:** [July 26, 2018, 9:54am UTC](https://discourse.mozilla.org/t/image-gallery-assessment/24687/20 "2018-07-26T09:54:32Z")

</div>

Hi there @impresently!

This is a tricky aspect of JavaScript, and I don’t blame you for having trouble with it. Let’s try to clear things up.

When a function is run as a direct result of an event firing, due to an event listener being added to the object on which the event fires, the function implicitly has an event object available inside its lexical scope (i.e. inside the function, but not outside it). The reason we write `e`, or `event`, or in this case `clickedImage` as a parameter is to give a definition to this event object — i.e. a name we can refer to it as.

So in this case, each time the loop is run, the `displayThumb()` function is defined, and we add an event listener to the `newImage` created on each round of the loop that makes it so that `displayThumb()` is run when the image in question is clicked on.

By the way, it would arguably be more efficient and better practice to define the function only once, outside the loop, rather than each time it runs (see our version at [https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/gallery/main.js](https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/gallery/main.js)), but yours still works OK.

So the event object passed into the function each time an image is clicked (`clickedImage` in your case) varies depending on which image was clicked. It contains information relevant to the image that was clicked.

Its `target` attribute contains a reference to the `image` itself — “the target of the event”. This is why when you do `clickedImage.target`, you can directly access the properties available on image. We can therefore use `getAttribute('src')` to access the contents of the image’s `src` attribute (the path to the image), etc.

Now, we also need to talk about the order in which things are run around loops. When you run a loop and it has a function inside it, the different loop iterations all run first, then the functions inside the loop iterations will run afterwards.

This is why the second code example DOESN’T work properly. By the time the loop iterations have all run, `newImage`'s `src` value is equal to the path to the last image. The event listeners are all set up correctly, but the function will always set the main image displayed to that last image.

If you instead get the `src` from `e.target.getAttribute()`, the value will be relative to the image clicked on, not the value of `newImage` after the loops have all run, which is always equal to the last image.

Does that help? Happy to discuss some more if you are still not clear.

[Next page](https://discourse.mozilla.org/t/image-gallery-assessment/24687.md?page=2)
