Upon script load, a random item from an array will be displayed and recorded in a separate array

I'm working on a fun code project where I aim to display random animal names in different colors that change when a specific keyboard key is pressed. The challenge I'm facing is that the first random animal name in a random color only appears after pressing either the "r" or "t" key, rather than showing up right at the beginning when the script starts running. I've attempted placing the initial display outside the event listener function but then encountered issues with saving the occurrence in the saveData array. I prefer not to add additional code just to save the first occurrence if possible. Here's a snippet of my code:

<!DOCTYPE html>
<html lang="en">
...

The desired output should look like this:

const showAnimal = () => {
    // Code for displaying random animals in colors
}

document.addEventListener('keydown', (event) => {
    // Event listener for changing animals on key press
});

showAnimal(); 

I need assistance in ensuring that a random name in a random color appears as soon as the script begins and is correctly saved in the saveData array along with subsequent occurrences triggered by keyboard inputs. Any suggestions on how to achieve this?

Answer №1

Hello there! 👋 I think I've come up with a possible solution for you to try out

  1. To start, I suggest moving all of your code outside of the showAnimals function
  2. Next, separate your code into different functions to improve readability
  3. Eliminate any duplicate code that follows the same logic
  4. Lastly, create a new function that incorporates your desired logic in an eventListener and call it when the page is loaded addAnimal(direction)

//Extracting code from showAnimal()
const animals = { dog: "yellow", cat: "black", fish: "blue", mouse: "gray" };
const colors = Object.keys(animals);
const name = Object.values(animals);

const numOfAnimals = 15;
let num = 0;

var saveData = [];

const displayAnimals = (
  randomText,
  randomColor
) => {
  if (num < numOfAnimals - 1) {
    document.getElementById("animals").innerText = `${randomColor}`;
    document.getElementById("animals").style.color = randomText;

    console.log(randomColor);
    console.log(randomText);
  } else {
    console.log(saveData);
  }
};

const selectRandomFeature = (name, colors) => {
  const randomTextIndex = Math.floor(Math.random() * name.length);
  const randomColorIndex = Math.floor(Math.random() * colors.length);

  var randomText = name[randomTextIndex];
  const randomColor = colors[randomColorIndex];

  return [randomText, randomColor, randomTextIndex, randomColorIndex];
};

const addAnimal = (direction) => {
  const [randomText, randomColor, randomTextIndex, randomColorIndex] =
    selectRandomFeature(name, colors);

  saveData.push({
    text: randomText,
    color: randomColor,
    direction: direction,
  });

  displayAnimals(randomText, randomColor, randomTextIndex, randomColorIndex);

  num++;
};

document.addEventListener("keydown", (event) => {
  if (event.key === "r" || event.key == "t") {
    const direction = event.key == "r" ? "left" : "right"; 
    addAnimal(direction);
  }
});

addAnimal("right");

Give this solution a go and see if it helps you out! 🧙‍♂️

Answer №2

Due to the function being called only on the eventListener, it didn't load when the page initially loaded. By calling the function before the eventListener and storing the values in an array, the issue can be resolved. Moreover, there is a missing "t" at direction:right on line 49 of your code. Below is the updated code with these changes implemented. Kindly provide feedback.

 const displayAnimals = (randomText, randomColor, randomTextIndex , randomColorIndex) => {
        if (num < numOfAnimals - 1) {        
            document.getElementById("animals").innerText  = `${randomColor}`;   
            document.getElementById("animals").style.color = randomText;

            console.log(randomColor);
            console.log(randomText);
        } else {
            console.log(saveData)
        }
    }

    const [randomText, randomColor, randomTextIndex , randomColorIndex] = selectRandomFeature(name, colors);

    saveData.push({"text": randomText, "color": randomColor, "direction": randomColorIndex})
    // call function here so it shows when script loads
    displayAnimals(randomText, randomColor, randomTextIndex, randomColorIndex);

    document.addEventListener('keydown', (event) => {
        const [randomText, randomColor, randomTextIndex , randomColorIndex] = selectRandomFeature(name, colors);

        if (event.key === 'r') {            
            if (randomTextIndex == randomColorIndex) {
                saveData.push({"text": randomText, "color": randomColor, "direction":"left"})
            } else {
                saveData.push({"text": randomText, "color": randomColor, "direction":"left"})
            }          
            displayAnimals(randomText, randomColor, randomTextIndex , randomColorIndex);  
            num++;   
        } else if (event.key === 't') { 

            if (randomTextIndex == randomColorIndex) {
                saveData.push({"text": randomText, "color": randomColor, "direction":"right"})
            } else {
                saveData.push({"text": randomText, "color": randomColor, "direction":"right"})
            }   
            displayAnimals(randomText, randomColor, randomTextIndex , randomColorIndex);         
            num++;                        
        }        
    });
}  
showAnimal()

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

Utilize the fetch function within a React functional component

I have been experimenting with different methods to fetch data only once before rendering, but I am encountering some challenges: It is not possible to call dispatch in componentDidMount as there is a restriction that it can only be done in Functional c ...

Is it possible to modify the contents within the JSP div tag without replacing them through an AJAX call?

In my JSP, I face a scenario where there is a div tag with scriptlet content that pulls data from the database every time a request is received from the server. Previously, I was refreshing the entire page with each update, which not only loaded all the re ...

AngularJS static list with dynamically changing content

Seeking inspiration on creating an AngularJS information monitor with a maximum of 6 rows. The display should show new rows at the top, pushing out the oldest row from the bottom when there are already 6 rows visible. Rows can also disappear unexpectedly. ...

Creating full-width divs using BootstrapLearn how to easily create full-width div

Bootstrap is being utilized in my current project. I have been creating divs inside columns, but they are not extending to the full width of the columns. Below is a snippet of the code: <!DOCTYPE html> <html lang="en"> <head> ...

If you're not utilizing v-model.lazy, Vue3 Cleave js may encounter functionality issues

I am currently experimenting with cleavejs to format the thousand separator in my input numbers. I've noticed a strange behavior where if I input 1000.123, it displays as 1,000.12 which is the correct format. However, the v-model value remains as 1000 ...

The useEffect hook is triggering multiple unnecessary calls

Imagine a tree-like structure that needs to be expanded to display all checked children. Check out this piece of code below: const { data } = useGetData(); // a custom react-query hook fetching data from an endpoint Now, there's a function that fin ...

Guidelines for setting up Kendo notifications using an angularjs service

I have successfully defined the Kendo notification in my Angular service. However, when I try to use it with the line uiService.notify.error("You missed some required fields.");, I am getting an error that says "Cannot read property 'show' of nul ...

Remove underlining from a Custom Link when hovering over it

Is there a way to remove the blue underline from my custom donate button? I created it by going to Appearance -> Menus -> Custom Link. The issue is that this custom link (donate button) is inheriting the same CSS as the navigation menu items, which I ...

Using Javascript libraries on a Chromebook: A comprehensive guide to getting started

Doing some coding on my chromebook and wondering if it's possible to download and utilize libraries such as jQuery. Would really appreciate any assistance with this! ...

Tips for executing Cross-Origin-Requests from Firebase Hosting to an AWS Lambda function

Excuse me, I'm still new to web development. I have a basic single-page website hosted on Firebase hosting that retrieves some information from an AWS Lambda function (I didn't use Google Cloud because it didn't support outbound requests fo ...

Is there a way to prevent users from selecting certain days in ion-datetime?

After searching through the official documentation, I couldn't find a solution. I am in need of a function similar to the jQuery datepicker beforeshowday function. My goal is to disable all weekends (Saturday and Sunday) in upcoming dates so that user ...

Effective way to manage Angular scope without resorting to $parent.$parent

After doing some research, I have not been able to find a solution that addresses my particular issue. Here is what I know: ng-if and ng-repeat create isolated scopes. Avoid using $parent.someProperty. Using $parent.$parent.someProperty is strongly disc ...

Is there a more straightforward alternative method to retrieve the title attribute from an input within a table cell?

Could you please help me with extracting the title attribute of the input located in the 2nd column (th) of the row with the "row_selected" class from the following table? Here's a link to the table. <table id="tabla_descuentos" class="tablesorter ...

ng-view does not support ng-repeat rendering

I have a basic app using ng-view and ng-repeat. Initially, it worked fine without ng-view, but after switching to ng-view, the ng-repeat stopped functioning correctly. Oddly, when I clicked on the "menu" link, it displayed another set of $var instead of ch ...

Adaptive Style Sheets Strategy

The images below depict the concept I am trying to achieve. The first image shows a longer width while the second one represents a shorter width. The red blocks are positioned on the right and left sides, with the yellow block adjusting its width based on ...

Top strategies for avoiding element tampering

What is the best solution for handling element manipulation, such as on Chrome? I have a button that can be hidden or disabled. By using Chrome's elements, it is possible to change it from hidden/disabled to visible/enabled, triggering my click functi ...

How come I am able to send back several elements in react without the need to enclose them in a fragment

This piece of code is functioning properly in React, displaying all the names on the page. However, I am questioning why it is returning multiple elements as a React component. Shouldn't they be wrapped in a single fragment? function App() { const n ...

"Firebase offers the flexibility to have several 'apps' configured, both on the client side and the server

Currently, I have a firebase app set up in my project for SSR using firebase-admin. However, I now want to add firebase@8 to be able to utilize it on the client-side and eventually apply firestore rules. The issue arises when I try to use firebase@8, I enc ...

Trouble with jQuery addClass function when trying to add to a specific object variable

I'm attempting to give an error class to an input textbox to inform the user that their input is invalid. Within the change event, I am referencing what seems to be the input field and storing it in a variable. However, calling addClass on the var ...

Initiating, halting, and rejuvenating a timer in JavaScript

Here is a simple code snippet where I'm experimenting with starting, stopping, and resetting a JavaScript timer. The goal is to have a timer running on a page that sends a message once it reaches the end of its countdown before restarting. The stop b ...