Andre
Andre

Reputation: 13

Javascript Array Undefined

I keep getting the error links[i] is undefined.
I define it explicitly and yet it keeps giving me that error -- any ideas?

I am trying to do unobtrusive image rolovers on 5 links that I have.

function loadImages(){
    path = 'uploads/Splash-4/nav/'; 
    links = new Array();

    for (i=1;i<=5;i++){
        var id = "link-"+i;
        var defaultState = '<img src="' +path+i+'.jpg" border="0" />';
        links[i] = document.getElementById(id);

        // Place all image linksinto anchor
        links[i].innerHTML = defaultState;

        // What to do on mouseover
        links[i].onmouseover = function() { 
            links[i].innerHTML = '<img src="' +path+i+'a.jpg" border="0" />';
        }
        // What to do on mouse oUt
        links[i].onmouseout = function() {
            links[i].innerHTML = defaultState;
        }
    }
}
window.onload = loadImages;

HTML:

 <a href="?page=Profile" id="link-1"></a>
 <a href="?page=for-sale" id="link-2"></a><br />
 <a href="?page=testimonials" id="link-3"></a><br />
 <a href="?page=free-home-appraisal" id="link-4" /></a><br />
 <a href="?page=contact-me" id="link-5"></a><br />

Upvotes: 1

Views: 5528

Answers (3)

Anthony Mills
Anthony Mills

Reputation: 8784

First off, you should be saying:

var links = [];

It's generally discouraged to use the Array constructor itself, and by not specifying var, you're making the links variable reside in the global space, which is generally bad.

Now, as to your actual problem.

Your event handlers are carrying a reference to the path and i variables from the outer scope, but by the time they're actually encountered, the variable i has the value 6 -- not what you intended at all! In order to fix that, you can change:

    // What to do on mouseover
    links[i].onmouseover = function() { 
        links[i].innerHTML = '<img src="' +path+i+'a.jpg" border="0" />';
    }
    // What to do on mouse oUt
    links[i].onmouseout = function() {
        links[i].innerHTML = defaultState;
    }

to

    // What to do on mouseover
    links[i].onmouseover = (function(path, i) {
        return function () {
            links[i].innerHTML = '<img src="' +path+i+'a.jpg" border="0" />';
        };
    })(path, i);
    // What to do on mouseout
    links[i].onmouseout = (function(i) {
        return function () {
            links[i].innerHTML = defaultState;
        }
    })(i);

This creates a new closure to hold the variables you want to capture. This way the inner i can still be, oh, 3 while the outer i goes to 6.

Upvotes: 6

Yanick Rochon
Yanick Rochon

Reputation: 53531

The problem is that when your onmouseover() function gets called, your variable i = 6 because your last iteration yielded i = 6, causing the loop to end. Therefore, you must protect i somewhere. For example :

function loadImages(){
    path = 'uploads/Splash-4/nav/'; 
    var links = [];

    for (i=1;i<=5;i++){
        (function(j) {
            var id = "link-"+j;
            var defaultState = '<img src="' +path+j+'.jpg" border="0" />';
            links[j] = document.getElementById(id);

            // Place all image linksinto anchor
            links[j].innerHTML = defaultState;

            // What to do on mouseover
            links[j].onmouseover = function() { 
                links[j].innerHTML = '<img src="' +path+j+'a.jpg" border="0" />';
            }
            // What to do on mouse oUt
            links[j].onmouseout = function() {
                links[j].innerHTML = defaultState;
            }
        })(i);  // call the anonymous function with i, thus protecting it's value for
                // the mouseover/mouseout

    }
}

Upvotes: 2

Andy
Andy

Reputation: 856

Your code snippet doesn't include a declaration of the variable links. If you haven't defined it elsewhere (i.e., if it's a local variable), you'll need to do it here:

Instead of

links = new Array();

You could do

var links = new Array();

One example can be found here.

If you have declared it elsewhere, it could be that this line

document.getElementById(id);

is returning null.

Upvotes: 0

Related Questions