Using JavaScript Object Constructor to alter text color

Seeking some guidance as a newbie here on how to deal with a problem I'm currently tackling. I understand that using an object constructor may not be the most efficient way to handle this, but I'm eager to enhance my knowledge of objects. My query revolves around finding something akin to this.function that can refer to all other objects that did not initiate my function. Here is the goal I aim to achieve:

<!doctype HTML>
<html>

<head>
  <title>Test</title>
  <style type="text/css">
    a {
      text-decoration: none;
      color: black;
    }
    
    a:visited {
      text-decoration: none;
      color: black;
    }
  </style>
</head>

<body>
  <ul>
    <li><a href="#" id="one"> Test</a> </li>
    <li><a href="#" id="two"> Test again</a> </li>
    <li><a href="#" id="three">Tester </a></li>
    <li><a href="#" id="four"> Testify</a> </li>
  </ul>
  <script>
    var first = document.getElementById('one');
    var second = document.getElementById('two');
    var third = document.getElementById('three');
    var fourth = document.getElementById('four');

    var colorChange = function(theID) {
      this.id = theID;
      this.formatContent = () => {
        this.id.style.color = "red";
      };
    }

    test = new colorChange(first);
    testAgain = new colorChange(second);
    tester = new colorChange(third);
    testify = new colorChange(fourth);

    function createEventListeners() {
      if (first.addEventListener) {
        first.addEventListener("click", test.formatContent, false);
      }
      if (second.addEventListener) {
        second.addEventListener("click", testAgain.formatContent, false);
      }
      if (third.addEventListener) {
        third.addEventListener("click", tester.formatContent, false);
      }
      if (fourth.addEventListener) {
        fourth.addEventListener("click", testify.formatContent, false);
      }
    }

    function init() {
      createEventListeners();
    }

    if (window.addEventListener) {
      //call init() on page load
      console.log("> Adding TC39 Event Listener...");
      window.addEventListener("load", init, false);
    } else if (window.attachEvent) {
      console.log("> Adding MS Event Listener...");
      window.attachEvent("onload", init);
    }
  </script>
</body>

</html>

Upon clicking one of the li items, you'll observe that its color changes to red. However, the issue lies in the fact that this change persists when you click another li item. I thought about instructing the browser to revert all other objects back to black when the formatContent() function is executed. Is there a simple way to achieve this?

Here's a link to a pen for your reference: https://codepen.io/seanbarker182/pen/JexPVz

Thank you in advance for any assistance provided!

Answer №1

To modify the appearance of your content, simply adjust the formatContent method:

this.formatContent = () => {
    if (this.id.style.color == "black") {
        this.id.style.color = "red";
    } else {
        this.id.style.color = "black";
    }
};

UPDATE:

If you want only the selected item to be highlighted in red, start by creating an array:

var elements = [first, second, third, fourth];

Then iterate through it within the function and reset all to black:

this.formatContent = () => {
    elements.forEach(function(elem) {
        elem.style.color = "black";
    }
    this.id.style.color = "red";
};

Answer №2

To gain knowledge about objects, utilizing the prototype can be an effective method to achieve your desired outcome:

var colorChange = function (theID) {
  this.id = theID;
  this.instances.push(this);
  this.formatContent = () => {
  this.revertColors();
  this.id.style.color = "red"
  };
}

colorChange.prototype.instances = [];
colorChange.prototype.revertColors = function() {
  this.instances.forEach(instance => (instance.id.style.color = "black"))
}

This particular code stores instances on the prototype object that is shared by all the class instances upon initialization. This enables you to access and modify this array from any instance as needed.

var first = document.getElementById('one');
var second = document.getElementById('two');
var third = document.getElementById('three');
var fourth = document.getElementById('four');

var colorChange = function (theID) {
this.id = theID;
  this.instances.push(this);
  this.formatContent = () => {
  this.revertColors();
  this.id.style.color = "red"
  };
}

colorChange.prototype.instances = [];
colorChange.prototype.revertColors = function() {
  this.instances.forEach(instance => (instance.id.style.color = "black"))
}

test = new colorChange(first);
testAgain = new colorChange(second);
tester = new colorChange(third);
testify = new colorChange(fourth);

function createEventListeners() {
   if (first.addEventListener) {
    first.addEventListener("click", test.formatContent, false);
  } if (second.addEventListener) {
    second.addEventListener("click", testAgain.formatContent, false);
  } if (third.addEventListener) {
    third.addEventListener("click", tester.formatContent, false);
  } if (fourth.addEventListener) {
    fourth.addEventListener("click", testify.formatContent, false);
  }
}

function init(){
createEventListeners();
}

if (window.addEventListener) {
  //call init() on page load
   console.log("> Adding TC39 Event Listener...");
   window.addEventListener ("load", init, false);
}
else if (window.attachEvent) {
   console.log("> Adding MS Event Listener...");
   window.attachEvent ("onload", init);
}
a {
  text-decoration: none;
  color: black;
}

a:visited {
  text-decoration: none;
color: black;
}
<html>
<head>
<title>Test</title>
</head>
<body>
<ul>
<li><a href="#0" id="one"> Test</a> </li>
<li><a href="#0" id="two"> Test again</a> </li>
<li><a href="#0" id="three">Tester </a></li>
<li><a href="#0" id="four"> Testify</a> </li>
</ul>
</body>
</html>

Answer №3

Discover a more efficient approach to achieve this without the need for IDs, requiring only one event listener to be set.

Check out this simplified example:

// Access the main ul element and add a click
// event listener to it. This will capture events that
// bubble up the DOM from other clicked elements
// (event propagation)
const ul = document.querySelector('ul');
ul.addEventListener('click', handleClick, false);

// Access the list items
const lis = document.querySelectorAll('ul li');

function handleClick(e) {

  // Retrieve the classList property from the event target
  const { classList } = e.target;

  // Iterate over the list items and reset their color
  [...lis].forEach(li => li.classList.remove('active'));

  // apply a red class to the clicked element
  classList.add('active');
}
.active { background-color: red; }
<ul class="colors">
  <li>Test</li>
  <li>Test again</li>
  <li>Tester</li>
  <li>Testify</li>
</ul>

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

Tips for retaining component data while navigating between components in vue js

If I have two elements, the first one is named X: <template> <input required type='text' v-model.trim="number"> <input type="date" v-model="date" > <button @click='allData(number,date)'>ok</button> <t ...

Tips for dynamically adjusting an iframe's content size as the browser window is resized

Currently, I am in the process of building a website that will showcase a location on a map (not Google Maps). To achieve this, I have utilized an iframe to contain the map and my goal is for the map to adjust its width based on the width of the browser wi ...

Having difficulties injecting a Service into a TypeScript Controller

I recently started working with TypeScript and I created a controller where I need to inject a service in order to use its methods. However, I am facing an issue where I am unable to access the service functions and encountering an error. Error TypeError ...

Is it necessary to download all npm packages when starting a new project?

I recently started learning about npm packages and node. I noticed that when installing packages, they create numerous folders in the "node modules" directory. This got me thinking - when starting a new project, do I need to re-install all these packages ...

Go through the embedded classes within the WWW::Selenium module

Is there a way in the `WWW::Selenium` library to loop through this HTML structure and extract the hrefs? <div class="myGengo_wrap full_width"> <h1>Dashboard</h1> <div class="blue list"> <span class="title">Sections ...

I'm struggling to make this script replace the values within the table

I am struggling with a script that I want to use for replacing values in a google doc template with data from a google sheet. The script is able to recognize the variables and generate unique file names based on the information from the google sheet. Howev ...

Tab knockout binding

I have a section in my HTML with 2 tabs. The default tab is working properly, but when I attempt to switch to the other tab, I encounter an error. Can anyone provide assistance in determining why this error occurs? Here is the HTML code: <ul class="na ...

How to close a Bootstrap modal after a successful AJAX request

There seems to be an issue with closing the modal after a successful login when using a sign-in href link that toggles the modal and loads a page within an iframe. I have tried adding the line $('#myModal').modal('hide'); to close the ...

Control the options of the Select menu using ajax

Consider having two dropdown menus <select id=first> <option value="1">1</option> <option value="2">2</option> <option value="3">3</option> <option value="4">4</opti ...

Menu icon in Next.js/React/Tailwind not triggering close action when clicked again, causing responsiveness issue

Hey there, I'm relatively new to working with Next.js and React. Right now, I'm tackling the challenge of creating a responsive navbar that toggles open and closed when clicking on the hamburger icon (and should also close when clicked outside th ...

The items in the Bootstrap dropdown are not displaying

I am currently working on a project using Angular 12, and I encountered an issue with my Bootstrap dropdown menu not displaying any items. Below is the HTML code snippet causing the problem: <nav class="navbar navbar-expand navbar-dark"> ...

The images on the Shopify platform are becoming increasingly fuzzy

I'm facing an issue where the images I add to my Shopify site using the Brooklyn theme appear blurry unless resized to a small scale. The dimensions of the images are 1748 x 1240 at 300dpi. My intention is to implement a JQuery image slider (lightsli ...

Button activates SVG animation

Currently, I am working on an animation for a button using SVG. The animation utilizes the classes .is-loading and .is-success. However, when I click on the button, the animation does not execute as expected. I'm having trouble identifying the error w ...

Leveraging the power of jQuery/javascript in conjunction with Google Forms

Currently, I am attempting to utilize jQuery and JavaScript with an iframe that contains a Google form. The code snippet is displayed below: <body> <iframe id="myFormFrame" src="https://docs.google.com/forms/d/smfjkafj809890dfafhfdfd/viewform?emb ...

The button component in my React application is not functioning as expected, despite utilizing the useState and useEffect hooks

I'm having trouble with my Button not working, even though I am using useState and useEffect Check out the code below: import React, { useState, useEffect } from "react"; // import Timeout from "await-timeout"; import ...

When a sidebar is added, Bootstrap 5 cards that are supposed to be displayed in a row end up being shown in a column instead

When I have a row of Bootstrap 5 cards that display correctly, but then add a sidebar that causes them to stack in a column instead of remaining in a row. How can I maintain the row layout even with the addition of a sidebar using specific CSS classes or p ...

What is the best way to retrieve an object from a POST request using Angular AJAX calls in a NODEJS environment?

When the button is clicked, a method will be called. The code for this is as follows: .controller('templeDetailsList', function ($scope, $http, $ionicModal) { $scope.starclick = function(){ var newFav = [{ ...

Loading MySQL data into different div compartments using AJAX

Apologies for creating this topic, I tried searching for the answer but couldn't find the solution. Currently, I am fetching data from MySQL using AJAX and it's working fine with one div. However, I'm having trouble loading each variable in ...

Transmitting data from Javascript/Ajax to a form

I am using jQuery to calculate a price: $('.label_1').click(function(){ var total = 0; $('.option_1:checked').each(function(){ total += parseInt($(this).val()); }); $('#total').html(' ...

Is there a way to continuously submit a form in React every 10 seconds, even if it includes events?

I have a form with input fields where I collect data upon form submission. However, I want the form to submit automatically every 10 seconds without the need to click a button or press enter. I tried using useEffect to create an interval, but it resulted i ...