aaron-prindle
aaron-prindle

Reputation: 3297

Difficulty With Click Event Listener In Closure

I'm currently working on the Udacity Course 'Javascript Design Patterns' and I am having some trouble with my embarrassingly titled assignment 'Cat Clicker'. You should be able to click one of the cat names on the list and it should increment the 'Cat count' span. I can't seem to get the click event listeners to work properly for the "cat_list". Once I put the event listener in a closure it no longer seems to do anything. Without the closure, only the last cat gets the event listener. Any information would be much appreciated, thanks. Also information regarding debugging clicks would also be appreciated.

JSFiddle of code: http://jsfiddle.net/pzagjdx4/1/ Source code:

index.html

<html>
<body>
  <span > Cat count: </span>
  <span id="cat_span">0</span>
  <div id="cat_div">
  </div>
  <div id="cat_list">
  </div>
  <script src="cat-clicker.js"></script>
</body>
</html>

cat-clicker.js

function catClick(){
    var cat_span = document.getElementById("cat_span");
    var number = cat_span.innerHTML;
    number++;
    cat_span.innerHTML = number;
}

function listClick(name, id_num){
    document.getElementById("cat_div").innerHTML = '<p id="cat_name_'+name+'">'+name+'</p>\
                     <img id="cat_img_'+id_num+'" src="cat.jpg">';
}


var Cat = function(input_name, id_num) {
    var name = input_name;
    var id_num = (function() {
        var id = 0;
        return function() { return id++; };
    })();
    var cat_list = (function(name, id_num){
        var list = [];
        return function() {list.append([name, id_num])};
    })(name, id_num);
    document.getElementById("cat_list").innerHTML += '<p id="cat_list_'+name+'">'+name+'</p>';
    // var new_list = document.getElementById("cat_list_"+name);
    // new_list.addEventListener('click', catClick, false);
    //THIS IS WHERE THE PROBLEM IS=====
    (function(name, id_num){
        var new_list = document.getElementById("cat_list_"+name);
        return function() {new_list.addEventListener('click', catClick, false)};
    })(name, id_num);
    //=====
    var div = document.createElement('div');
    document.getElementById("cat_div").innerHTML = '<p id="cat_name_'+name+'">'+name+'</p>\
                     <img id="cat_img_'+id_num+'" src="cat.jpg">';
    var new_cat = document.getElementById("cat_img_"+id_num);
    new_cat.addEventListener('click', catClick, false);

};

var cat_0 = new Cat('Kitty');
var cat_1 = new Cat('Cat');

Upvotes: 0

Views: 309

Answers (2)

mjzr
mjzr

Reputation: 241

Also you have only one cat image because your overriding the first image:

document.getElementById("cat_list").innerHTML = '<p id="cat_list_'+name+'">'+name+'</p>';

Change = to +=.

Upvotes: 1

epascarello
epascarello

Reputation: 207531

You are returning a function, and that new function is never called.

(function(name, id_num){
    var new_list = document.getElementById("cat_list_"+name);
    return function() {new_list.addEventListener('click', catClick, false)};  <-- does nothing
})(name, id_num);

Should just be

(function(name, id_num){
    var new_list = document.getElementById("cat_list_"+name);
    new_list.addEventListener('click', catClick, false);
})(name, id_num);

With the way that code is written, there is no need to even have that function wrapping it.

Upvotes: 1

Related Questions