Modifying the Color of Array Elements using JavaScript

When attempting to change text color on hover, an error message is displayed:

Uncaught TypeError: Cannot read property 'style' of undefined at HTMLDivElement

<a data-tab="Tab 1">
  <div class="tab-link__text">Tab1</div>
</a>
<a data-tab="Tab 2">
  <div class="tab-link__text">Tab2</div>
</a>


 let tabLinks = document.getElementsByClassName('tab-link__text');
 let tabLinksArr = Array.prototype.slice.call( tabLinks )

  tabLinksArr[0].style.color = "red"; //This successfully changes the color

  for (i=0; i < tabLinksArr.length; i++) {
    tabLinksArr[i].addEventListener('mouseover', function(){
        tabLinksArr[i].style.color = "red"; //However, this does not work
    });
  }

The styling works fine when outside the for loop, but encounters issues inside.

Answer №1

One issue to note in your code snippet is that the variable i is set to 2 after the for loop finishes, causing an error when trying to set the style of tabLinks[2], which doesn't exist. To fix this, it's important to keep a reference to the correct tabLink:

let tabLinks = document.getElementsByClassName('tab-link__text');

for (let i = 0; i < tabLinks.length; i++) {
  let tabLink = tabLinks[i];
  tabLink.addEventListener('mouseover', () => {
    tabLink.style.color = "red";
  });
}
<a data-tab="Tab 1">
  <div class="tab-link__text">Tab1</div>
</a>
<a data-tab="Tab 2">
  <div class="tab-link__text">Tab2</div>
</a>

Additionally, consider the following:

1) Using single quotes ' instead of double quotes "

2) Utilizing arrow functions => rather than function keyword

3) Declare variables with let i

4) Prefer using array.forEach() or for(el of array) over

for(let i = 0; i < array.length; i++)

5) Modify element classes instead of styles directly.

let tabLinks = document.getElementsByClassName('tab-link__text');
[...tabLinks].forEach(tabLink =>
  tabLink.addEventListener('mouseover', () =>
    tabLink.classList.add('hovered')));
.hovered {
  color: red;
}
<a data-tab="Tab 1">
  <div class="tab-link__te`xt">Tab1</div>
</a>
<a data-tab="Tab 2">
  <div class="tab-link__text">Tab2</div>
</a>

Answer №2

The reason for this issue is that the variable i in the function context becomes equal to tabLinks.length since the function is called before the for loop completes. To troubleshoot, you can use console.log to check the value of the i variable in your event listener. Since tabLinks[tabLinks.length] does not exist (the last index should be

tabLinks[tabLinks.length - 1]</code), you encounter the error <code>Cannot read property 'style' of undefined
. Therefore, you should avoid using the i variable at this point and instead use the event target like so:

for (i=0; i < tabLinks.length; i++) {
    tabLinks[i].addEventListener('mouseover', function(e){
        e.target.style.color = "red";
    });
}

I hope this explanation helps!

Answer №3

Give this a try. I have confirmed that this code is functioning correctly.

<a data-tab="Tab 1">
  <div class="tab-link__text">Tab1</div>
</a>
<a data-tab="Tab 2">
  <div class="tab-link__text">Tab2</div>
</a>

<script>
let tabLinks = document.querySelectorAll('.tab-link__text');
tabLinks.forEach(tabLink => {
     tabLink.addEventListener('mouseover', () => {
           tabLink.style.color = "red"
     });
});
</script>

Appreciate it

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

Issue with interactions between datepicker and jQuery dialog box

I am working with a datatable that displays user data, and each row has an edit button to open an edit form. I am opening this form using a jQuery dialog box and submitting it using ajax submit. However, when loading the form, the datepickers are not worki ...

Tips for Loading a Selected Option from an Ajax Call in Angular JS on Page Load

How do I automatically set the selected option from an ajax call when the page loads? I am fetching zones using an ajax call and I want to trigger the change function of the zones on page load in order to set the selected option of the cities select box. ...

disabling a submit button

I am new to coding and need help disabling a button on document load. Can someone assist me with this? Here is my current code snippet: $(document).ready(function() { setTimeout("check_user()", 250); }); Your guidance is greatly appreciated! ...

The Tailwind preset is generating CSS code, but the webpage is not displaying the intended styles

Can anyone explain why the preset is generating CSS in the output file, but the styles are not displaying in the browser? When I manually write CSS in newstyle.css, it gets outputted to output.css and renders correctly in the browser. I attempted adding t ...

Six Material-UI TextFields sharing a single label

Is there a way to create 6 MUI TextField components for entering 6 numbers separated by dots, all enclosed within one common label 'Code Number' inside a single FormControl? The issue here is that the label currently appears only in the first tex ...

Browser lacks proper credentials for passport authentication

I'm currently learning how to incorporate user authentication using passport.js. I have successfully set up a basic passport "local" strategy on the server side, along with a single POST route for logging in users. When testing with insomnia, everythi ...

Registering a component in Vue.js and checking for errors in component registration

Recently, I attempted to use the vuejs-countdown-timer component in one of our projects but encountered an error. Unknown custom element: - did you register the component correctly? For recursive components, make sure to provide the "name" option. The ...

Is JavaScript not having an impact on your HTML code?

I am attempting to create a dynamic number change when the user interacts with the "range-slider" element, but the number is not updating as expected. Below is the code I have written: var rangeSlider = function() { var slider = $(".range-slider"), ...

Accessing a JSON string correctly using JavascriptSerializer in JavaScript

When working with JavaScript, I encountered an issue where the data retrieved from a data table and converted to javascriptSerializer was not refreshing correctly when changing dataset selection parameters. The problem occurred when trying to populate a ne ...

What is the best method for injecting a factory dependency into an angular controller?

Situation:- I have a factory named testFactory. Up until now, I was defining my controller like this: app.controller('testCtrl',function($scope,testFactory) { testFactory.Method1(){ //working fine} } However, before minimizing the file, I def ...

Running an express server on localhost with nginx: A step-by-step guide

Is it possible to run the express server using Nginx on localhost? And if so, how can this be accomplished? const express = require('express') const app = express() const port = 3000 app.get('/', (req, res) => res.send('Hello ...

Restricting the Vue for-loop results to display only the current item in use

Currently, I am utilizing a for-loop to retrieve all of my posts, followed by employing a partial to obtain a list of all the usersThatUpvoted on that post. <div v-for="p in posts" style="padding: 16px"> <div> &l ...

Encountering Uncaught Runtime Error in NextJs

Encountered an issue with my Nextjs website development where I am seeing an Unhandled Runtime Error. Error: Server-rendered HTML does not match text content. **Warning:** Discrepancy found between server and client text content: Server says "160 mins ag ...

Pass a variable value as a parameter to a jQuery function using code-behind

Within my code behind, I am retrieving the [IDphoto] from an SQL database. My goal now is to pass this IDphoto as a parameter to a jQuery function upon onClick. How can I achieve this? Code behind sb.AppendFormat("<a onclick='popup()' href=& ...

Is it possible to create floating unordered lists using Bootstrap in HTML?

Is there a way to float text left or maintain list order in the HTML code of my page while using a dense CSS from this bootstrap template? For example, I would like my list to remain organized regardless of how many items are added: https://i.sstatic.net ...

Unexpected Issue with JavaScript Ajax (Using jQuery.post): The Promise State Turns to "Rejected"

Recently, I've been encountering some issues while trying to debug my jQuery.post() call. The responses I'm getting are quite puzzling and I'm at a loss on how to proceed next. If anyone has any suggestions or insights, I would greatly appre ...

Is there a way to eliminate empty arrays from my data?

I'm dealing with this PHP code snippet. public function display_children($parent,$level){ try { $cmd = $this->connection->prepare('SELECT mem,pid from mytree where pid = ?'); $cmd->execute(array($parent)); ...

What is the best way to resize an image to fit its surroundings within a nested box?

Have you ever heard of a website called SPAM? It has a unique homepage that I want to replicate using JavaScript, jQuery, and some CSS. My main challenge is figuring out how to adjust the image size to match the center box on the page. I want to create th ...

Navigational menu header leads to specific location on the page

I need the dropdown menu header to both open the related menu and display the content of the first element of the submenu, which is an anchor link on the page. Here is the HTML code for the Dropdown Menu: <div class="collapse navbar-collapse" id="myNa ...

Guide on implementing factory updates to the display

I am attempting to update a reference within my factory in an asynchronous fashion, but I am not seeing the changes reflected in my view. View <div ng-repeat="Message in Current.Messages">{{Message.text}}</div> Controller angular.module(&ap ...