"Exploring the concept of Undefined in Javascript Arrays

I keep encountering the issue links[i] is undefined. Even after explicitly defining it, the error persists. Any thoughts on why this might be happening?

I am attempting to implement unobtrusive image rollovers for 5 links that I currently 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);

        // Insert all image links into anchor
        links[i].innerHTML = defaultState;

        // Mouseover action
        links[i].onmouseover = function() { 
            links[i].innerHTML = '<img src="' +path+i+'a.jpg" border="0" />';
        }
        // Mouseout action
        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 />

Answer №1

To begin with, it is recommended to start by declaring:

var links = [];

Using the Array constructor directly is not advised, and failing to use var will lead to the links variable being stored in the global scope, which is generally undesirable.

Moving on to address your specific issue.

Your event handlers are referencing the variables path and i from the outer scope, but when they are actually executed, the variable i holds the value of 6 -- contrary to what you intended! To rectify this, you can update the code as follows:

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

to

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

This approach creates a new closure to encapsulate the desired variables. Consequently, the inner i can retain a value like 3 while the outer i assumes the value of 6.

Answer №2

The issue arises when the onmouseover() function is triggered, setting your variable i = 6 due to the previous iteration setting it as such, ultimately ending the loop prematurely. To avoid this, you need to safeguard the value of i in some manner. One approach is:

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);

            // Populate all image links into anchor
            links[j].innerHTML = defaultState;

            // Define behavior on mouseover
            links[j].onmouseover = function() { 
                links[j].innerHTML = '<img src="' +path+j+'a.jpg" border="0" />';
            }
            // Define behavior on mouseout
            links[j].onmouseout = function() {
                links[j].innerHTML = defaultState;
            }
        })(i);  // Invoke the anonymous function with i to preserve its value for
                // the mouseover/mouseout events

    }
}

Answer №3

Your current code snippet is missing the declaration of the variable links. If this variable has not been defined elsewhere (i.e., if it's a local variable), you will need to declare it in this section:

Instead of

links = new Array();

You should consider using

var links = new Array();

An example showcasing this can be seen here.

If you have already declared it earlier on, the issue could potentially lie with this line of code:

document.getElementById(id);

This might be returning null.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

An elaborate warning mechanism in Redux-observable that does not trigger an action at the conclusion of an epic

I'm currently working on implementing a sophisticated alert system using redux and redux-observable. The requirements are: An action should request an alert: REQUEST_ALERT An action should create an alert and add an ID: SET_ALERT (handled in the ep ...

Customizing Passport JS Bearer strategy for various endpoints and HTTP REST operations

I'm currently using the BearerStrategy and I am attempting to configure different strategies for each endpoint or method within the same router. After reviewing the documentation, I have not come across any references to this particular scenario othe ...

Turning JSON data into an array format, omitting the keys

Can someone help me with a query that will retrieve a specific column from the database and return it in this format: [ { "tenantName": "H&M" }, { "tenantName": "McDonalds" } ] I would like to transform ...

What is the best way to store a downloaded video from the server?

I am currently in the process of downloading a video from a server using JavaScript XHR (specifically Angular $http GET with response type 'blob'). My question is, how can I save this downloaded video to a Chrome application's local storage ...

The custom error page in NextJS is failing to display

In my custom pages/404.ts file, I have coded the following: export default function NotFound() { return <h1>404 - Page Not Found</h1> } Additionally, there is another page that displays a 404 error when the organization is null: import Error ...

Error: Unable to access the currentTime property as it is not defined

Incorporating Videojs into my react application has presented a challenge. I am attempting to set the current time of the videojs player, but keep encountering an error that reads "cannot read property currentTime of undefined". Below is my approach: var ...

What is the origin of this mysterious error?

I'm working on a function to format various types of variables and utilize a toString() method. It's handling complex objects, arrays, and circular references flawlessly. However, when testing it on a jQuery object using format($("body")) with l ...

Combine loop results into a string using jQuery

When using jQuery, I need to append a multiline string to an element by adding a string return from each value in a for loop. $("songs-table-tr").append('tr id="songs-table-tr'+count+'" style="display: none">\ ...

JavaScript function issue with automatic tabbing

Encountered an issue while utilizing this in our asp.net application. The main goal is as follows: When in a textbox -> tab once MaxLength is reached When in a checkbox -> tab once the control is toggled with the keyboard (spacebar) Other than bu ...

Change the blue line to a crisp, clean white

Is it possible to customize the color of the blue line that appears when clicked? class Greetings extends React.Component { render() { return <div>Greetings {this.props.name}</div>; } } ReactDOM.render( <div> <p tabInde ...

What is the method for generating a binary numpy array with two columns from a list of strings?

Input: A list of strings provided below: ['x', 'x', 'y', 'z', 'z', 'x', 'y'] Desired Output: I am looking to convert this list into a numpy array as shown: array([[ 1, 0, 0], ...

Customize the yellow background color of Safari's autofill feature by following these simple

When I open this image in Safari, this is what I see: https://i.stack.imgur.com/KbyGP.png However, this is the code I have: https://i.stack.imgur.com/4wEf0.png References: How to Remove WebKit's Banana-Yellow Autofill Background Remove forced ye ...

Disabling scrolling on body while scrolling a superimposed element

I am working on creating a dynamic image gallery for browsers that support Javascript. The gallery consists of thumbnails that lead to full-size photos displayed in a table layout, complete with navigation links and captions. This table is centered using f ...

Do I need to include a callback in my AWS Lambda handler function?

What is the function of the callback in the lambda handler? It appears to be utilizing the sns variable and I am looking to make some modifications to the variables. exports.handler = function(event, context, callback) { console.log("AWS lambda and ...

Personalizing a Doughnut Graph

Currently in the process of creating a donut chart I am looking to achieve a design similar to the image below, where the values are displayed within the colored segments import DonutChart from 'react-d3-donut'; let data = [{ count ...

In Reactjs, you can prevent users from selecting future dates and times by modifying the KeyboardDateTimePicker component

I am currently using the Material UI KeyboardDateTimePicker component and have successfully disabled future dates with the disabledFuture parameter. However, I am now looking for a way to disable future times as well. Any suggestions or solutions would b ...

Positioning divs around a circle can be quite challenging

Among my collection of divs with various classes and multiple child divs representing guests at a table, each main div symbolizes a specific restaurant table type. I have created a jsfiddle for demonstration. http://jsfiddle.net/rkqBD/ In the provided ex ...

Rendering HTML with jQuery using AJAX: Step-by-step guide

Within my webpage, I have implemented a select box that contains a list of various books. The purpose of this select box is to allow the user to choose a book and then click a submit button in order to view the chapters of that book on a separate page. Ho ...

Incorporating AJAX in jQuery mobile to transmit data to a controller in CodeIgniter

I'm currently facing an issue where despite successfully retrieving the latitude and longitude values from the geolocation feature in Google Chrome, I am unable to pass these values to the index function within the controller named Add. When attemptin ...

Error injecting Angular components

Here is the structure of my HTML file: <html> <head> <title>PLD Interaction pattern</title> <link href="css/bootstrap.min.css" rel="stylesheet" type="text/css"/> </head> <body ng-app="myT ...