5

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?

2
  • what does the rendered html in the debug tools look like? Commented Feb 18, 2015 at 0:17
  • Just normal divs as you would expect from the code. Commented Feb 18, 2015 at 6:37

1 Answer 1

3

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);
Sign up to request clarification or add additional context in comments.

2 Comments

This isn't working. It gives just the same result: only the last one has an onclick event. Very strange. Do you have any other ideas?
Finally it works! I combined your initial answer (_key and the nested-function) with your edited answer. Now it works. It doesn't make very much sense, especially because I haven't really used JavaScript before. Anyway, thank you!

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.