Having trouble populating the box with CSS through JavaScript

https://i.sstatic.net/HH00Z.png

Currently working on a quiz website using JavaScript, and trying to dynamically fill the color in the box as the quiz progresses with the help of CSS. However, facing some challenges with the code implementation. Any suggestions or insights? It seems like there might be an issue with the game.js class not being able to locate progressBarFull. Any assistance or guidance would be highly appreciated.

//////game.js/////

const question = document.getElementById('question');
const choices = Array.from(document.getElementsByClassName('choice-text'));
const progressText = document.getElementById('progressText');
const scoreText = document.getElementById('score');
const progressBarFull = document.getElementById('progressBarFull');

let currentQuestion = {};
let acceptingAnswer = false;
let Score = 0 ;
let QuestionCounter = 0;
let AvailableQuestion = [];

let questions = [
    {
         question:"Inside which HTML element do we put JavaScript?",
         choice1: "<script>",
         choice2: "<javascript>",
         choice3: "<js>",
         choice4: "<scripting>",
         answer: 1
        },
        {
         question:"What is correct syntax for referreing to an external script called xxx.js",
         choice1: "<script href='xxx.js'>",
         choice2: "<script name='xxx.js'>",
         choice3: "<script src='xxx.js'>",
         choice4: "<script file='xxx.js'>",
         answer: 3
        },
        {
         question:"How do you write Hello in an alert box",
         choice1: "msgbox('Hello World')",
         choice2: "alertbox('Hello World')",
         choice3: "msg('Hello World')",
         choice4: "alert('Hello World')",
         answer: 4
        },
]


// Constants

const CORRECT_BONUS = 10;
const MAX_QUESTIONS = 3;
const INCORRECT = 10;

startgame = (  ) =>{
    QuestionCounter=0;
    Score=0;
    AvailableQuestion=[...questions];
    console.log(AvailableQuestion);
    getNewQuestion();
};

getNewQuestion =()=> {
    if(AvailableQuestion.length == 0 || question>= MAX_QUESTIONS){
        // Go to the endpage
        return window.location.assign('/end.html');
    }
    QuestionCounter++;
    progressText.innerText = `Question ${QuestionCounter} / ${MAX_QUESTIONS}`;

    
    // Update The ProgressBar
    progressBarFull.style.width = `${(QuestionCounter / MAX_QUESTIONS) * 100}
    %`
    console.log((QuestionCounter / MAX_QUESTIONS) * 100)


    const questionIndex = Math.floor(Math.random() * AvailableQuestion.length);
    currentQuestion = AvailableQuestion[questionIndex];
    question.innerText = currentQuestion.question;


    // foreach iterates through the choices
    choices.forEach( choice => {
        const number = choice.dataset['number']; 
        // getting number from data-number --- game.html
        choice.innerText = currentQuestion['choice' + number]
    })
    AvailableQuestion.splice(questionIndex, 1);

    acceptingAnswer = true
};

choices.forEach(choice => {
    choice.addEventListener("click", e=> {
        if(!acceptingAnswer) return;
        
        
        acceptingAnswer = false;
        const selectedChoice = e.target;
        const selectedAnswer = selectedChoice.dataset["number"];
        
        // Different ways of using conditions
        // const classToApply = 'incorrect';
        // if(selectedAnswer == currentQuestion.answer){
        //     classToApply = 'correct;'
        // }

        const classToApply = selectedAnswer == currentQuestion.answer ? 'correct' : 'incorrect';
        if (classToApply === 'correct'){
            incrementScore(CORRECT_BONUS)
        }
        else{
            decrementScore(INCORRECT)
        }
        // console.log(classToApply)

        selectedChoice.parentElement.classList.add(classToApply)
        setTimeout(() => {
            selectedChoice.parentElement.classList.remove(classToApply)
            getNewQuestion()
            
        }, 250);

       

        // console.log(selectedAnswer == currentQuestion.answer)
    })

})

incrementScore = num => {
    Score += num;
    scoreText.innerText = Score;
}

decrementScore = num => {
    Score -= num;
    scoreText.innerText = Score;
}

startgame()

/////game.html///

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Game - Play</title>
    <link rel="stylesheet" href="app.css" >
    <link rel="stylesheet" href="game.css">
</head>
<body>
    <div class="container">
        <div id="game" class="justify-center flex-column">
            <div id="hud">
                <div id="hud-item">
                    <p id="progressText" class="hud-prefix">
                        Question
                    </p>
                    <div id="progressBar">
                        <div id="progressBarFull"> </div>
                    </div>
                </div> 
                <div id="hud-item">
                    <p class="hud-prefix">
                        Score
                    </p>
                    <h1 class="hud-mainText" id="score">
                        0
                    </h1>
                </div> 
            </div>
            <h2 id="question">
                Answer to this question?
            </h2>
            <div class="choice-container">
                <p class="choice-prefix">A</p>
                <p class="choice-text" data-number="1">Choice 1</p>
            </div>
            <div class="choice-container">
                <p class="choice-prefix">B</p>
                <p class="choice-text" data-number="2">Choice 2</p>
            </div>
            <div class="choice-container">
                <p class="choice-prefix">C</p>
                <p class="choice-text" data-number="3">Choice 3</p>
            </div>
            <div class="choice-container">
                <p class="choice-prefix">D</p>
                <p class="choice-text" data-number="4">Choice 4</p>
            </div>
        </div>
    </div>
            <script src="game.js"></script>
</body>
</html>

//////game.css////

.choice-container{
    display: flex;
    margin-bottom: 0.5rem;
    width: 100%;
    font-size: 1.8rem;
    border:0.1rem solid rgb(86, 235, 0.25);
    background-color: white;
}

.choice-container:hover{
    cursor: pointer;
    box-shadow: 0 0.4rem 1.4rem 0 rgb(86, 165, 235, 0.5);
    transform: translate(-0.1rem);
    transition: transfor 150ms;
}

.choice-prefix{
    padding:1.5rem 2.5rem;
    background-color: #56a5eb;
    color: white;

}

.choice-text{
    padding: 1.5rem;
    width: 100%;
}

.correct{
    background-color: #28a745;
}

.incorrect{
    background-color: #dc3545;
}

/* HUD */
#hud {
display: flex;
justify-content: space-evenly;
}

.hud-prefix{
    text-align: center;
    font-size: 2rem;
}

.hud-main-text{
    text-align: center;
}

#progressBar{
    width: 20rem;
    height: 4rem;
    border: 0.3rem solid #56a5eb;
    margin-top: 0.9rem;

}

#progressBarFull{
    height: 3.4rem;
    background-color:#56a5eb;
    width: 0%;
}

Answer №1

One glaring issue that needs to be addressed is the invalid style being applied to progressBarFull.

It appears that there are spaces present in your JavaScript code:

progressBarFull.style.width = `${(QuestionCounter / MAX_QUESTIONS) * 100} %`

This mistake leads to setting an incorrect style, which may not even be visible when inspecting the DOM. A percentage (%) specifier should immediately follow the numeric value for it to be valid.

Answer №2

Below is an example that may be suitable for your needs. It utilizes jQuery but can easily be adapted to Vanilla JS.

$(function() {
  function updateProgressBar(current, total) {
    var percentage = Math.floor((current / total) * 100);
    $("#progressBarFull").css("width", percentage + "%");
  }

  $("button").click(function() {
    updateProgressBar($(this).val(), 3);
    $(this).prop("disabled", true).next().prop("disabled", false);
  });
});
#hud {
  display: flex;
  justify-content: space-evenly;
}

.hud-prefix {
  text-align: center;
  font-size: 2rem;
}

.hud-main-text {
  text-align: center;
}

#progressBar {
  width: 20rem;
  height: 4rem;
  border: 0.3rem solid #56a5eb;
  margin-top: 0.9rem;
}

#progressBarFull {
  height: 3.4rem;
  background-color: #56a5eb;
  width: 0%;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="hud">
  <div id="hud-item">
    <p id="progressText" class="hud-prefix">
      Question
    </p>
    <div id="progressBar">
      <div id="progressBarFull"> </div>
    </div>
  </div>
  <div id="hud-item">
    <p class="hud-prefix">
      Score
    </p>
    <h1 class="hud-mainText" id="score">
      0
    </h1>
  </div>
</div>
<button value="1">Answer 1</button>
<button value="2" disabled="true">Answer 2</button>
<button value="3" disabled="true">Answer 3</button>

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

Passing Data from Child to Parent Components in ReactJS

I'm new to React and JavaScript, currently working on a website. I've encountered an issue with passing data between components from child to parent. Here's the scenario: In my App.js script, I'm using react-router-dom for routing. I ...

A custom JavaScript function designed to facilitate the downloading of a file that includes the user's input directly to the user

Is there a way to use javascript to generate a file based on user input and provide it as a download without storing it on the server? For instance, imagine a scenario where a user is using an application and they want to download their work by clicking ...

Explore by the anchor tag

I've recently implemented a search bar utilizing Bootstrap. This is the code for the search bar: <div class="md-form mt-0"> <input class="form-control" id="myInput" type="text" placeholder="Sear ...

What is the best location for storing buddypress css files?

Recently, I set up buddypress on a fresh WordPress installation and am interested in developing a child theme with personalized styles. Following advice from the buddypress codex, I copied the buddypress theme from plugins > buddypress > bp-template ...

Click here to see the image

I'm looking to enhance an image with a hyperlink. This is the code I have so far. How can I make the image clickable? success: function(data, textStatus, jqXHR){ $.each( data, function( idx, obj ) { // $( "<img>" ).attr( "src", '/ima ...

How to conceal the border in a Bootstrap datetimepicker

I am currently using a bootstrap datetimepicker and I would like to eliminate the border around the days and months in the cell. This is my attempt so far: .bootstrap-datetimepicker-widget td { border: 0px !important; } I have also included a ...

What is the best way to position two elements inline?

I was trying to create a container named project-item that looks like the image linked below: https://i.stack.imgur.com/6XzZ9.png My goal was to align the project logo and the title (h3) in one line, but I struggled to find a suitable solution. This is ...

Challenges with line height in IE when adjusting font size in textarea

I'm facing an issue with adjusting the font size in a textarea using JavaScript. While it works perfectly in Firefox, there are some problems in IE. Specifically, the line-height does not change accordingly. This results in gaps between lines when the ...

Using Node.js to execute JavaScript with imported modules via the command line

Having limited experience with running JavaScript from the command line, I am facing a situation where I need to utilize an NPM package for controlling a Panasonic AC unit, which includes a wrapper for their unofficial API. My objective is to create a sim ...

`A dilemma with dynamic tooltip functionality in JavaScript`

I am currently utilizing the Tooltipster jquery plugin, which I find to be quite useful. However, I am facing a challenge in making my tooltips dynamic. Despite thinking it should be a simple task, I seem to be struggling with it. It could be due to fatig ...

Modal displaying undefined value with jQuery

I have been attempting to display data from a database in a table within a modal using the provided code. However, I keep encountering an issue with receiving an undefined value. Here is the accompanying image: https://i.sstatic.net/fPTIW.png Modal HTML ...

What is the best way to establish a link between the index and the JSON object?

I am working with a JSON object that maintains a specific sequence within it. var sample={ "sample": [ { "example": [ { "sequence": 1, }, { "sequence":2 }, { "sequ ...

Positioning oversized images in a React Native application

Looking to showcase two images side by side using React Native, where I can customize the screen percentage each image takes up. The combined size of the images will exceed the horizontal screen space available, so I want them to maintain their original di ...

Ensuring the correct class type in a switch statement

It's been a while since I've used Typescript and I'm having trouble remembering how to properly type guard multiple classes within a switch statement. class A {} class B {} class C {} type OneOfThem = A | B | C; function test(foo: OneOfThe ...

Removing a function when changing screen size, specifically for responsive menus

$(document).ready(function () { // retrieve the width of the screen var screenWidth = 0; $(window).resize(function () { screenWidth = $(document).width(); // if the document's width is less than 768 pixels ...

Choose a different PHP value when the selection changes

I am looking to create a seamless connection between a select element and an input text field without the need to refresh the page. Here is an example of what I am trying to achieve: <select name="name_select" id="my_select"> <option value="1" ...

Tips on organizing error messages into a list within React

After receiving the response from my Spring Boot API, I need to properly format it in my React app: Array(4) 0: {field: 'lastName', message: 'size must be between 3 and 50'} 1: {field: 'username', message: 'size must be b ...

ImageMapster: Showcase all regions with a highlight effect, but choose a particular region when clicking on a list item, displaying other regions with reduced opacity

I recently came across the following example: http://jsfiddle.net/jamietre/gjH5c/ My goal is to achieve the same functionality, but with a slight tweak - I want all areas to be highlighted upon loading. To accomplish this, I used staticState: true. Howeve ...

Merging Values in Angular 5 through Objects

I am developing a scheduling application using an Angular 5.1 framework and NoSQL database. Here is a glimpse of my sample data: staff = [ { name: 'John Stewart', updatedTimestamp: '1520221418024', ...

Produce a vue attribute

I am looking to display a property in my component. My template includes: <v-flex v-for="c in components"> <component :is="c.component" v-bind="c.prop"></component> </v-flex> And in the script: ... mounted(){ ...