0

I'm confused. I want to construct a gallery wherein you can click on any image and you have the full-scale image superimposed on the document (kinda like with facebook galleries).

The gallery's thumbnails are displayed with some PHP. It looks like this:

$i = 0;

while($img_dir = mysqli_fetch_assoc($gallery_q))
{
    $i++;

    echo
    '
        <div class="entry"><div class="image" id="' . $img_dir['dir'] . '">
<img id="img' . $i . '" src="' . $img_dir['thumb_dir'] . '" /></div></div>
    ';

}

I then fetch the number of images with json_encode and produce a bunch of event listener with a loop, like so:

for(var i = 1; i <= nbImg; i++)
{ 
    document.getElementById("img" + i).addEventListener("click", display(i));
}

The display function being the following:

function display(i)
{
document.getElementById("body").insertAdjacentHTML("afterBegin",
'<div id="display"><div><img src="' + document.getElementById("img" + i).parentNode.getAttribute("id") + '"></div>');

style.insertAdjacentHTML("beforeend",
"#display{z-index: 20; position: fixed; width: 1000px; height: 1000px; left: 50%; top: 10%; margin-left: -600px;");

}

And well, it works.. except display() is called without any regards for whether I click on the image or not. But when I restrain this behavior to only one image (that is, the event listener isn't in a loop and no argument is passed to the function; it just displays a preset image) then all is fine. The event is triggered when I click.

It's actually not the first time I encounter this phenomenon of the listening function being triggered not matter what event I ask the event listener to be on the lookout for. It happens most often with alert and I honestly can't figure out why. Can someone help me?

2 Answers 2

4

You can't assign the function like that. Adding the () immediately invokes the function (to pass the function, omit the () - but you'll also lose the ability to pass i in, event would instead be passed in since it's the first param that the function passed to addEventListener has):

document.getElementById("img" + i).addEventListener("click", function() {
    display(i);
});

You'll probably notice that i is always the last iterated loop var, so you want to wrap this in a closure:

for(var i = 1; i <= nbImg; i++) { 
    (function(i) {
        document.getElementById("img" + i).addEventListener("click", function() {
            display(i)
        });
    })(i);
}
Sign up to request clarification or add additional context in comments.

Comments

3

the reason display is being called has to do with this code. you're invoking the display function as opposed to referencing it. replace the display function with a closure.

for (var i = 1; i <= nbImg; i++) {
  document.getElementById("img" + i).addEventListener("click", function() {
    display(i)
  });
}

3 Comments

You've explained the issue correctly. What about the solution?
Thanks, it works and I now understand the underlying principle
your welcome. if you're new to javascript, i'd recommend reading up on closures and scope because problems like this can and will pop up frequently.

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.