Possible Duplicate:
Event handlers inside a Javascript loop - need a closure?
I want to simply assign onclick events to a series of li elements within an unordered list. Instead of doing it the messy way by either defining lots of unique IDs and manually adding the events to each li element I'd like to do it programatically with a for loop.
html:
<ul id="homeNav">
<li><a title="Back to home page" href="">home</a></li>
<li><a title="Play" href="">play</a></li>
<li><a title="About the site?" href="">about</a></li>
<li><a title="Latest development news and info." href="">dev blog</a></li>
<div class="clear"></div>
</ul>
Javascript:
window.onload = function()
{
var parentList = document.getElementById('homeNav');
var listItems = parentList.getElementsByTagName('li');
var numItems = listItems.length;
for(var i = 0; i < numItems; i++)
{
listItems[i].onmouseover = function()
{
listItems[i].getElementsByTagName('a')[0].style.color = 'blue';
}
listItems[i].onmouseout = function()
{
listItems[i].getElementsByTagName('a')[0].style.color = '#cccccc';
}
}
}
I get the error listItems[i] is undefined
To me it looks like the event is literally looking for the i index variable instead of using the number assigned to it at the time of the event being added to the trigger, or maybe the i variable isn't within the closures' scope?
-
I'd rather not use jQuery. I'd like to be comfortably proficient with Javascript before I dabble in JS libraries and frameworks.Lee– Lee2012年09月25日 19:05:25 +00:00Commented Sep 25, 2012 at 19:05
-
I just created this JSFiddle and it seems to work fine.Codeman– Codeman2012年09月25日 19:06:53 +00:00Commented Sep 25, 2012 at 19:06
-
@Pheonixblade9 because this function will never be called.Igor Shastin– Igor Shastin2012年09月25日 19:09:19 +00:00Commented Sep 25, 2012 at 19:09
-
@IgorShastin gotcha, I just never experienced the errorCodeman– Codeman2012年09月25日 19:17:20 +00:00Commented Sep 25, 2012 at 19:17
3 Answers 3
The variable is not avilable in the event, you can use this..
for(var i = 0; i < numItems; i++)
{
listItems[i].onmouseover = function()
{
this.getElementsByTagName('a')[0].style.color = 'blue';
}
listItems[i].onmouseout = function()
{
this.getElementsByTagName('a')[0].style.color = '#cccccc';
}
}
1 Comment
this equivalent.I'm not sure, but i would think & check
var listItems = parentList.getElementsByTagName('li');
listItems[i]
... I'm not sure that you're doing it 2) do a console.log (listItems) to see what's it, and remember about array - object difference. that's all for now, have to go... sorry for the brief answer, hope it helps.
Comments
there is problem in your code. on mouseover or mouseout value of i would be equal to numItems; as these events will get called after finish of for loop. so you should save context.
function bindEvent(elem){
elem.onmouseover = function()
{
elem.getElementsByTagName('a')[0].style.color = 'blue';
}
elem.onmouseout = function()
{
elem.getElementsByTagName('a')[0].style.color = '#cccccc';
}
}
window.onload = function()
{
var parentList = document.getElementById('homeNav');
var listItems = parentList.getElementsByTagName('li');
var numItems = listItems.length;
for(var i = 0; i < numItems; i++)
{
bindEvent(listItems[i]);
}
}