Trouble unserstanding Undefined error

Just when I think I’m understanding javascript… :frowning:

The following returns the error i is Undefined on the line where i.style.visibility = ‘visible’; is in the function.

How come this is so when var i = document.createElement(‘INPUT’); was declared globally outside the function? Could someone explain why this is happening? Thanks.


var l = document.createElement('A');
l.id = 'title_link';
l.href = '#';
l.innerHTML = 'Click to change element tag.';
l.onclick = title_link_clicked();
l.style.visibility = 'visible';
document.body.appendChild(l);

var i = document.createElement('INPUT');
i.id = 'title_input';
i.value = '';
i.style.visibility = 'hidden';
document.body.appendChild(i);

// Switch visibility
function title_link_clicked() {
	l.style.visibility = 'hidden';
	i.style.visibility = 'visible';
	return false;
}

l.onclick = title_link_clicked();

doesn’t do what you think it does. This will actually run title_link_clicked() immediately and assign l.onclick its return value. Since the function only returns false, your l element won’t get an onclick handler. And the function is also called before the i element is created, that’s the reason for the undefined error.

What you want to do is:

l.onclick = title_link_clicked;

You can also add this to your code:


l.addEventListener('click', title_link_clicked, false);

As said above, l.onclick means property access (l is the object, onclick is a property that happens to be a method also).


l.onclick = title_link_clicked();

means the function on the right side is executed, a function call.


l.onclick = title_link_clicked;

means the function on the right side is referenced, which is what you need.

Something like this:


// Switch visibility
function title_link_clicked() {
	l.style.visibility = 'hidden';
	i.style.visibility = 'visible';
	return false;
};

var l = document.createElement('A');
l.id = 'title_link';
l.href = '#';
l.innerHTML = 'Click to change element tag.';
//l.onclick = title_link_clicked;
l.addEventListener('click', title_link_clicked, false);
l.style.visibility = 'visible';
document.body.appendChild(l);

var i = document.createElement('INPUT');
i.id = 'title_input';
i.value = '';
i.style.visibility = 'hidden';
document.body.appendChild(i);

Of course, IE8- stay in the way: http://stackoverflow.com/questions/6348494/addeventlistener-vs-onclick.

Thanks folks, that really cleared a few things up.