0
votes

I have a problem with javascript. I need to add onclick listener for all img tags in my page, so click on an image should call imageClicked and pass element to function. but this code all time pass img src="../images/3.jpg" to function.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<link rel="stylesheet" href="style.css" type="text/css" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Sample Page</title>
</head>

<body onload="start()">
<script type="text/javascript">
    function start(){
        var images = document.getElementsByTagName("img");
        for ( var i = 0; i < images.length; i++) {
            var image=images[i];
            image.addEventListener('click', function(){
                imageClicked(image);
            });
        }
    }
    function imageClicked(image){
        alert(image.src)
    }
</script>
<div id="main">
    <div id="center">
        <button>نمایش اسلایدی</button>
    </div>
    <div id="gallery">
        <div id="img1" class="image">
            <img src="../images/1.jpg"></img>
            <div id="title">
                <label>عکس</label>
            </div>
        </div>
        <div id="img2" class="image">
            <img src="../images/2.jpg"></img>
            <div id="title">
                <label>عکس</label>
            </div>
        </div>
        <div id="img" class="image">
            <img src="../images/3.jpg"></img>
            <div id="title">
                <label>عکس</label>
            </div>
        </div>
    </div>
</div>

2
Title is not same as tags - hop

2 Answers

3
votes

That is because of the scope. Everytime you loop the image value is set again. And so it will always pass the last image in the loop.

You can do 2 thing. Use the this like below. Or create an anonymouse function.

function start(){
    var images = document.getElementsByTagName("img");
    for ( var i = 0; i < images.length; i++) {
        images[i].addEventListener('click', function(){
            imageClicked(this);
        });
    }
}

// Or even better

function start(){
    var images = document.getElementsByTagName("img");
    for ( var i = 0; i < images.length; i++) {
        images[i].addEventListener('click', imageClicked);
    }
}
function imageClicked(){
    alert(this.src); // this refers to the image
}

Anonymouse function:

function start(){
    var images = document.getElementsByTagName("img");
    for ( var i = 0; i < images.length; i++) {
        (function(image){
            image.addEventListener('click', function(){
                imageClicked(image); // Use the element clicked object (this)
            });
        })(images[i]);
    }
}
0
votes

What you want is something like this:

function start(){
    var images = document.getElementsByTagName("img");
    for ( var i = 0; i < images.length; i++) {
        images[i].addEventListener('click', function(){
            imageClicked(this);
        });
    }
}
function imageClicked(image){
    alert(image.src)
}

In the code you wrote, you copied the image element and then assigned an eventListener to the copy of the object. Because this copy was over-written multiple times, imageClicked was referred to by the only one that wasn't over-written, the last image. The this is to refer to the actual image element in the callback function.