Wednesday, February 22, 2017

[JavaScript][Resolved] Pass arguments to addEventListener listener function

Lines provided below are content in html file format with 5 images, load them into DOM and add onClick event listener to the elements. If user click an image, a log with added image order would be printed on console (also prompt the number in alert box). It is expected click ingthe first image shows number 0, second image shows number 1, click last image shows the number 4 is there are 5 images. However, sth go wrong and it prints incorrect numbers:

Incorrect result : 

No matter which image you clicked, it shows show alert and print out "the la"

Source code (with problem):

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<img src="http://farm3.static.flickr.com/2922/14413728054_09b1c10f91_b.jpg"/>
<img src="https://travelblog.expedia.com.hk/wp-content/uploads/2015/11/02%E5%8F%B0%E5%8C%97%E5%8D%81%E5%A4%A7%E6%96%87%E9%9D%92%E5%92%96%E5%95%A1%E5%BA%97-1024x768.jpg"/>
<img src="http://opinion.cw.com.tw/sites/default/files/blog_articles/main_image/images/caf---coffee-man-3760.jpeg"/>
<img src="http://img.gq.com.tw/userfiles/sm/sm645_images_A1/26439/2016022457172457.jpg"/>
<img src="http://pic.pimg.tw/muchael/1412326121-4088795190.jpg"/>

<script>
    window.onload = function() {
        imgs = document.getElementsByTagName("img");
        for(i=0; i<imgs.length; i++){
            imgs[i].addEventListener('click', function (e){
                showNum(i);
            });
        }
    };       

    function showNum(i) {
        alert(i);
        console.log(i);
    }       
</script>
</body>
</html>

Solution

To solve this problem , i used the method provided by howtocreate.co.uk : Using scope to remember the instances of the local variables. it works like a charm. For detail and if you want to know how it works, you can reference from the article : Passing variables to referenced functions shown at reference link.
<script>
    window.onload = function() {
        imgs = document.getElementsByTagName("img");
        for(i=0; i<imgs.length; i++){
            imgs[i].onclick = showNum(i);
        }
    };      

    function showNum(i) {
        return function(){
            alert(i);
            console.log(i);
        }
    }  
</script>
Or you can simply use this for doing the same job:
<script>
    window.onload = function() {
        imgs = document.getElementsByTagName("img");
        for(i=0; i<imgs.length; i++){
            imgs[i].onclick = (function(i){
                return function(){
                    alert(i);
                    console.log(i);
                }           
            })(i);

        }
    };       
</script>
Another solution provided by colleague :
<script>
    window.onload = function() {
        Array.from(document.getElementsByTagName("img")).forEach((img, i) => {
            img.addEventListener('click', (e) => {
                showNum(i);
            });
        })

    };       

    function showNum(i) {
        alert(i);
    }
</script>

Result:



Reference:

http://www.howtocreate.co.uk/referencedvariables.html

No comments :

Post a Comment