The bug is way too trivial: you are using
b_id
in
submit_letter(b_id)
. This is
one object shared by all the buttons. What is its value? The values assigned to this variable at the last iteration, 'Z'. One interesting question is this one: how this value, accessible via a
local variable (that is, a variable on stack, normally) can get to the event handler object. This question is not trivial at all: this is the effect of
closure. It is very important to learn this important advanced aspect of programming:
http://en.wikipedia.org/wiki/Closure_(computer_programming)[
^].
Understanding of closures in not so easy. If something is not clear in this article, please ask a question; I'll explain.
Here is how you can understand what's going on. Consider order of execution. In your loop, you only create function objects and assign them to the property
onclick
. You never call those functions before you complete the loop. Those functions are called a lot later, when the event is invoked as a result of the user's click. And when the call is performed
b_id
is used. Normally, this object would not even exist, as a local variables after leaving the stack frame. But the effect of closure (due to the use of the variable inside the handler) preserves this variable, so it could be used in the handler. And what is it's value? The value assigned back them, at the last iteration of the loop execution. Z.
Some more problems:
You don't need to split
alphabet
. To bad you did not show its definition, but I'm almost sure it is something like the string "ABCD....F". You can access each character directly, as
alphabet[index]
. Also, it's quite a bad idea to concatenate "btn". The attribute
id
value could better be "A", "B", etc. Moreover, you could assign some other attribute and use it, for example
name
, it would relax the uniqueness requirements. But your main problem is: you never use the attribute values assigned.
So, what would be the correct solution? Pretty simple: you need to use the argument of the button click handler. Let's forget my advice to assign any attribute values to the letters of alphabet. You could simply assign button texts (
innerHTML
) to those letters, or letters with some markup. Let's assume there are just letters, for simplicity (otherwise you can always extract that letter from
innerHTML
string). Then your handler may look like this:
b.onclick = function(eventInstance) {
submit_letter(eventInstance.target.innerHTML)
}
Note that
eventInstance.target
is the reference to your button which invoked the event. If you want to use some attributes, you can extract the attribute value from this object.
Please see:
https://developer.mozilla.org/en-US/docs/Web/API/Event[
^],
https://developer.mozilla.org/en-US/docs/Web/API/Event/target[
^].
—SA