Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamically creating elements and adding onclick event not working

I have a for loop that creates div-elements with IDs like 'category1', 'category2' etc. The loop goes through a key/value array, which looks something like this:

"0" : "Java",
"1" : "JavaScript",
"2" : "HTML"

So, the IDs of the divs are 'category' + the key.

Within the for-loop where the elements are added to the innerHTML of a container-div, I add an onclick-event.

This is the for-loop that I'm talking about:

for (var key in categories) {
    categoriesBlock.innerHTML += '<div class="category" id="category' + key + '">' + categories[key] + '</div>';

    document.getElementById('category' + key).onclick = function() { showPostsForCategory(key, categories[key]); }
}

where categories is the above array.

The problem is, the onclick is only working for the LAST element in the array. If I check with the Safari-debugger and type "category3.onclick" it says null. If I type "category4.onclick" (which is the last one) it returns the correct function.

How is this possible? And how to solve it?

like image 857
Jeroen Avatar asked Oct 19 '22 17:10

Jeroen


1 Answers

This is an issue with scoping. The click handler is pointing to the last value because that's what it ended up as when the loop ended. Here is a way to trap the value.

for (var key in categories) {        
    (function(){
      var _key = key;
      document.getElementById('category' + _key).onclick = function() { showPostsForCategory(_key, categories[_key]); }
    })();
}

Edit...

Also, string concatenation is not the ideal way to create html elements. In some browsers, there might be a delay between when you insert text, and when it becomes an actual html element.

var div = document.createElement('div');
div.onclick = function(){...};
categoriesBlock.appendChild(div);
like image 144
posit labs Avatar answered Oct 27 '22 09:10

posit labs