What could be the reason why both the add and remove functions are unable to work simultaneously within a JavaScript function?

Hi there! I recently started diving into JavaScript and encountered a little hiccup. I've been working on a dice game where images change randomly whenever a button is clicked.

The images transition from one to another, but I wanted to add a rolling effect to them. So, I went ahead and added some animations that rotated the images along both the X-axis and Y-axis. It seemed to work smoothly on the initial click, but failed thereafter.

To tackle this issue, I tried using classList.add() for applying the animation and classList.remove() to remove it. However, the removal function didn't quite do its job.

Here's a snippet of the HTML code I've been working on:

function roll() {
  document.querySelectorAll("img")[0].classList.add("rollEffect");
  document.querySelectorAll("img")[1].classList.add("rollEffect");
  var randomNumber1 = Math.floor(Math.random() * 6 + 1);
  var randomNumber2 = Math.floor(Math.random() * 6 + 1);
  var randomImage1 = "dice" + randomNumber1 + ".png";
  var randomImage2 = "dice" + randomNumber2 + ".png";
  document.querySelectorAll("img")[0].setAttribute("src", randomImage1);
  document.querySelectorAll("img")[1].setAttribute("src", randomImage2);

  if (randomNumber1 > randomNumber2)
    document.querySelector("h1").innerHTML = "Player 1 wins!!!";
  else
  if (randomNumber2 > randomNumber1)
    document.querySelector("h1").innerHTML = "Player 2 wins!!!";
  else
    document.querySelector("h1").innerHTML = "DRAW!!!";
  document.querySelectorAll("img")[0].classList.remove("rollEffect");
  document.querySelectorAll("img")[1].classList.remove("rollEffect");
}
.btn {
  background-color: #8843F2;
  border: 0;
  border-radius: 20px;
  color: #ffffff;
  font-family: 'Indie Flower', cursive;
  margin: 0 50px;
  padding: 1% 2%;
}

.container {
  width: 70%;
  margin: auto;
  text-align: center;
}

.dice {
  text-align: center;
  display: inline-block;
}

@keyframes rollClick {
  9% {
    transform: rotateX(30deg) rotateY(30deg)
  }
  18% {
    transform: rotateX(60deg) rotateY(60deg)
  }
  28% {
    transform: rotateX(90deg) rotateY(90deg)
  }
  37% {
    transform: rotateX(120deg) rotateY(120deg)
  }
  46% {
    transform: rotateX(150deg) rotateY(150deg)
  }
  55% {
    transform: rotateX(180deg) rotateY(180deg)
  }
  65% {
    transform: rotateX(210deg) rotateY(210deg)
  }
  76% {
    transform: rotateX(240deg) rotateY(240deg)
  }
  85% {
    transform: rotateX(270deg) rotateY(270deg)
  }
  90% {
    transform: rotateX(300deg) rotateY(300deg)
  }
  95% {
    transform: rotateX(330deg) rotateY(330deg)
  }
  100% {
    transform: rotateX(360deg) rotateY(360deg)
  }
}

.rollEffect {
  animation-name: rollClick;
  animation-duration: 0.1s;
}

body {
  background-color: #F9D371;
}

img {
  width: 80%;
}
<div class="container">
  <h1>Roll us</h1>
  <div class="dice">
    <p>Player 1</p>
    <img class="img1" src="dice6.png">
  </div>
  <div class="dice">
    <p>Player 2</p>
    <img class="img2" src="dice6.png">
  </div>
  <button class="btn" onclick="roll()">Roll</button>
 </div>

Answer №1

The JavaScript function responsible for adding the rolling animation class operates independently from any set animation durations.

It will execute at the speed allowed by the device's performance capabilities.

In your JS code, it will:

  1. apply the .rollEffect class to both images.
  2. assign a new image URL.
  3. display text indicating the outcome of the game.
  4. remove the .rollEffect class from both images.

All of this occurs as quickly as possible, in microseconds or even nanoseconds.
The animation is applied and removed so swiftly that it may not be perceptible.

Wait briefly before removing the animation class to ensure the animation completes before cessation.

This can be accomplished using setTimeout For instance:

  setTimeout(() => {
    document.querySelectorAll("img")[0].classList.remove("rollEffect");
    document.querySelectorAll("img")[1].classList.remove("rollEffect");
  }, 100); // <--- Setting 100 here will trigger the callback after 100ms, equivalent to the animation duration.

function roll() {
  document.querySelectorAll("img")[0].classList.add("rollEffect");
  document.querySelectorAll("img")[1].classList.add("rollEffect");
  var randomNumber1 = Math.floor(Math.random() * 6 + 1);
  var randomNumber2 = Math.floor(Math.random() * 6 + 1);
  var randomImage1 = `http://placekitten.com/g/${50*randomNumber1}/300`;
  var randomImage2 = `http://placekitten.com/g/200/${50*randomNumber2}`;
  document.querySelectorAll("img")[0].setAttribute("src", randomImage1);
  document.querySelectorAll("img")[1].setAttribute("src", randomImage2);

  if (randomNumber1 > randomNumber2)
    document.querySelector("h1").innerHTML = "Player1 wins!!!";
  else
  if (randomNumber2 > randomNumber1)
    document.querySelector("h1").innerHTML = "Player2 wins!!!";
  else
    document.querySelector("h1").innerHTML = "DRAW!!!";

  setTimeout(() => {
    document.querySelectorAll("img")[0].classList.remove("rollEffect");
    document.querySelectorAll("img")[1].classList.remove("rollEffect");
  }, 100);
}
.btn {
  background-color: #8843F2;
  border: 0;
  border-radius: 20px;
  color: #ffffff;
  font-family: 'Indie Flower', cursive;
  margin: 0 50px;
  padding: 1% 2%;
}

.container {
  width: 70%;
  margin: auto;
  text-align: center;
}

.dice {
  text-align: center;
  display: inline-block;
}

@keyframes rollClick {
  9% {
    transform: rotateX(30deg) rotateY(30deg)
  }
  /* Remaining keyframe declarations follow */
}

.rollEffect {
  animation-name: rollClick;
  animation-duration: 0.1s;
}

body {
  background-color: #F9D371;
}

img {
  width: 150px;
  height: 150px;
}
<div class="container">
  <h1>Roll us</h1>
  <div class="dice">
    <p>Player 1</p>
    <img class="img1" src="http://placekitten.com/g/200/300">
  </div>
  <div class="dice">
    <p>Player 2</p>
    <img class="img2" src="http://placekitten.com/g/300/200">
  </div>
  <button class="btn" onclick="roll()">Roll</button>
</div>

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 parsing data arrays in HTML templates

I have three variables and I created an array where I pushed all these three variables in. In my HTML template, I am using a table. I tried using *ngFor but it is not working, and also attempted string interpolation which also did not work. Currently, I ...

Acquiring HTML form data using JavaScript

Although it may seem trivial, I'm facing a challenge. I have an HTML form that is dynamically generated by JavaScript and populated with initial data fetched from the server. The form is displayed correctly with the pre-filled data. My goal is to allo ...

Discover the ins and outs of integrating YAML front matter into your destination directory path

I am looking to customize the path of my blog posts to include a fancy date format like /blog/2013/09/17 so that the links from my previous octopress blog remain intact. Within the YAML front matter on each markdown page, I have included the date informat ...

Updating the positions of Mesh objects in Three.js asynchronously

I'm currently working on a Three.js application where I am creating a grid to display various objects. These objects are rendered on the grid based on their positions, which are obtained from data fetched from a REST API that I poll every 300 millisec ...

What is the best way to link a single post to a collection of posts?

I am currently working on building a basic blog using PHP. My goal is to create a link from a post to a list of all posts on the blog, similar to the example shown below: Example of how I plan to display posts and a post viewer There are two distinct par ...

Perform an action when the timer reaches zero

I am working with a database entry that contains the following information: { _id:"fdjshbjds564564sfsdf", shipmentCreationTime:"12:17 AM" shipmentExpiryTime:"12:32 AM" } My goal is to create a timer in the front end ...

Creating interfaces for applications that are driven by events in JavaScript

When it comes to designing an application, traditional UML Class diagrams may not always be useful, especially for programs that do not heavily rely on classes. For instance, in a JavaScript application that is mainly event-driven, where you listen for eve ...

My method for updating form input properties involves switching the disable attribute from "false" to "true" and vice versa

I have a form that uses Ajax to submit data. Once the user submits the form, the text is updated to indicate that the data was sent successfully, and then the form is displayed with the fields filled out. I want to display the form but prevent users from r ...

Ui-router experiencing issues with nested view loading due to changes in URL

I have been developing an application and previously used ui-router successfully with Ionic. The issue I am facing now is that although the URL changes correctly as expected, nothing happens afterwards. I am certain that the template is being found because ...

What is the procedure for importing material UI components into the main class?

Hey there! I'm currently working on integrating a "SimpleAppBar" element into my React app design. Below is the code snippet for this element sourced directly from the Material UI official website: import React from 'react'; import PropType ...

A guide on restricting overflow in React Spring Parallax 'pages'

Currently, I have integrated React Spring Parallax () into my project found at this link: https://codesandbox.io/s/parallax-sticky-scroll-2zd58?file=/src/App.js Upon clicking the button to navigate to the next section, it is noticeable that the image over ...

Modify mouse pointer when an object is clicked using JavaScript

Greetings, I am in the process of designing a website for a client. I have encountered a challenge in changing the cursor icon when a user performs a mousedown on an object. There is an image on the webpage When the user clicks on the image, the cursor s ...

modifying the identification value in HTML and then reverting it

Although this may seem like messy code, I'm really in need of assistance with a problem that has stumped me. Currently, I am working on an E-shop project where I have modals for displaying products. Within these modals, there is a button that allows u ...

"Learn how to retrieve and assign a value to a select2 dropdown in Vue.js

Currently, I am utilizing vuejs to create and delete dynamic select elements, which is functioning properly. To view the working example, please click here: https://jsfiddle.net/nikleshraut/fgpdp700/2/ var vm = new Vue({ el: "#app", data: { opt ...

Can PHP encode the "undefined" value using json_encode?

How can I encode a variable to have the value of undefined, like in the JavaScript keyword undefined? When I searched online, all I found were results about errors in PHP scripts due to the function json_encode being undefined. Is there a way to represent ...

Using an array of JSON objects to set up a Backbone.js bootstrap-initialized application

Trying to bootstrap a backbone collection by using an array of JSON objects has led to some unexpected errors. When attempting to call reset on the collection object, an error from Backbone is thrown - Uncaught TypeError: undefined is not a function. Inte ...

Passing an ID in Next.js without showing it in the URL

I am looking to transfer the product id from the category page to the product page without showing it in the URL Category.js <h2> <Link href={{ pathname: `/product/car/${title}`, query: { id: Item.id, }, }} as={`/p ...

Using Vue.js to eliminate duplicate values from a filtered array of objects

How can I eliminate duplicate data from a v-for loop in Vue.js? I have an array of clients and another array of categories. When filtering the categories based on clientIDs, I noticed that there are duplicates present. Please choose a client from the opti ...

What is the process for extracting the value of a checkbox generated through JavaScript?

I recently came across a helpful post on Stack Overflow that provided sample code demonstrating how to display multiple list of checkboxes dynamically on a dropdown list. The function in the code was exactly what I needed for my webpage. However, I encount ...

Arrays contain multiple elements, not just a single item

Is it possible to display multiple objects in one container? For instance, I have an array let array = [1, 2, 3, 4, 5, 6, 7, 8, 9]; array.forEach((item, index) => ( <div> <div> item 1, 2, 3 </div> <div> item 4, 5, 6 </div ...