The clearInterval function in Javascript may not effectively halt an ongoing animation

Whenever I press a button, the element rotates using setInterval and clearInterval to stop rotation at a specific value by clearing the interval time t. Everything works perfectly except when I continually click the same button before the current animation finishes, the rotation does not stop as expected. The clearInterval function does not work in this scenario.

The following code showcases the issue:

var t; // interval 
var x = 0 ; // counter
var cal ; // element to rotate

function prepareRotatesX(){
    x=x+5;
    cal =document.getElementById("myCalendar");
    cal.style.transform="rotateX("+x+"deg)";
    
    if(x>360){ clearInterval(t); x=0;}
}

function rotate(){
   
    t = setInterval(function(){ 
      prepareRotatesX();
    }, 10);
}
#myCalendar{ 
                position: absolute;
                top:45px;
                left:20px;
                border: 2px solid blue;
                width: 210px;
                height:170px;
                background-color:blue;
            }
<div id="myCalendar">
     <!---HERE COME CALENDAR -->
 </div>
 <!-- make rotation-->
 <button id='bnext' onclick='rotate();'>Rotation</button>

How can we resolve the issue of stopping the rotation in this particular case?

Answer №1

If you want to ensure that a process is not run multiple times concurrently, one approach is to check if it is already running and exit if so. Once the operation is completed, you can then reset the interval.

var t; // interval 
var x = 0; // counter
var cal; // element to be rotate

function prepareRotatesX() {
  x = x + 5;
  cal = document.getElementById("myCalendar");
  cal.style.transform = "rotateX(" + x + "deg)";

  if (x > 360) {
    clearInterval(t);
    x = 0;
    t = null
  }
}

function rotate() {
  if (t) return;  // If 't' is defined, it means operation is in progress, so exit
  t = setInterval(function() {
    prepareRotatesX();
  }, 10);
}
#myCalendar {
  position: absolute;
  top: 45px;
  left: 20px;
  border: 2px solid blue;
  width: 210px;
  height: 170px;
  background-color: blue;
}
<div id="myCalendar">
  <!---CALENDAR CONTENT HERE-->
</div>
<!-- Start rotation with button click -->
<button id='bnext' onclick='rotate();'>Rotate</button>

Another option is to clear the interval and restart it instantly:

function rotate() {
  if (t) clearInterval(t)
  t = setInterval(function() {
    prepareRotatesX();
  }, 10);
}

Answer №2

Issue arises when the global declaration of variable t causes trouble. Moving t to a local scope within your code should resolve this problem (assuming you want the previous clicks rotation to continue).

If you wish to stop the previous click action, you can refer to the solution provided by @epascarello.

var x = 0 ; // counter
var cal ; // element to be rotate

function prepareRotatesX(t){
    x=x+5;
    cal =document.getElementById("myCalendar");
    cal.style.transform="rotateX("+x+"deg)";
    
    if(x>360){ clearInterval(t); x=0;}
}

function rotate(){
   var t; // interval 
    t = setInterval(function(){ 
      prepareRotatesX(t);
    }, 10);
}
#myCalendar{ 
                position: absolute;
                top:45px;
                left:20px;
                border: 2px solid blue;
                width: 210px;
                height:170px;
                background-color:blue;
            }
   <div id="myCalendar">
     <!---HERE COME CALENDAR -->
 </div>
 <!-- make rotation-->
 <button id='bnext' onclick='rotate();'>Rotation</button>

Answer №3

When implementing the rotate method that is triggered on click, it is essential to include a check for the defined interval and clear it if necessary. The updated code snippet below illustrates this:

var t; // interval 
var x = 0 ; // counter
var cal ; // element to be rotated

function prepareRotatesX(){
    x=x+5;
    cal =document.getElementById("myCalendar");
    cal.style.transform="rotateX("+x+"deg)";
    
    if(x>360){ clearInterval(t); x=0;}
}

function rotate(){
    if(t !== undefined) {
        clearInterval(t);
    }
    t = setInterval(function(){ 
      prepareRotatesX();
    }, 10);
}
#myCalendar{ 
                position: absolute;
                top:45px;
                left:20px;
                border: 2px solid blue;
                width: 210px;
                height:170px;
                background-color:blue;
            }
<div id="myCalendar">
     <!---CALENDAR CONTENT GOES HERE-->
 </div>
 <!-- initiate rotation with button click -->
 <button id='bnext' onclick='rotate();'>Rotate</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

Adjust the text size of a label in material-ui

Hey everyone, I'm struggling with something here. I need to adjust the font size of the label that goes along with my textfield. So far, I've only been able to change the font size of the input itself and not the label. Here's the code for ...

Difficulty parsing JSON in MVC .Net Core Controller

I am dealing with a Web Application built in ASP.Net Core 5 that communicates with a Web API in .Net Core. The data returned from the API in JSON format needs to be read from a file named landing.js. Despite the data being stored in the variable (data), I ...

Decoding the enigma of addEventListener in Nuxt: Unveiling the "referenceError: window is not defined" issue

I am currently working on developing a hamburger menu, but I have encountered an error. The error message states: ReferenceError: window is not defined. The issue seems to be within the created section of the code. <script> export default { ...

JavaScript will continue to run uninterrupted even after refreshing the webpage

Has anyone else encountered the issue of a javascript on a page continuing to run even after the page is refreshed? From what I understand, javascript is single-threaded and should stop running when the page is refreshed. Just to provide some background, ...

Exploring the Depths with a Javascript Canvas Deep Zoom Library

I am faced with the task of creating a detailed zoom mosaic using an HTML5 Canvas Element, consisting of thousands of roughly 512x512 images. However, I am striving to minimize reinventing the wheel in the process. Instead of merging numerous large images ...

problem with the video pathway in the javascript document

I'm currently in the process of putting together a Video gallery playlist using HTML, CSS, and JavaScript. So far, I've set up the html and css files along with two js files. The first js file contains all the video information as shown here: ...

Steps to implement an image zoom function triggered by a button click

I'm working on a school project that requires me to use only html, css, and javascript for creating a website. Currently, I'm designing a landing page with a button that will navigate the user to another page. My goal is to have the background im ...

Activate browser scrollbar functionality

Below is the HTML code snippet: <html> <head> <style> #parent { position : absolute; width : 500px; height : 500px; } #top { position : absolute; width : 100%; height: 100%; z-index : 5; } #bottom { position : absolute; width : 100%; ...

Select a random option from the dropdown menu

I have the following script: <script> function $(id) { return document.getElementById(id); } function getImage() { $('loader').src='/misc/images/loading.gif'; var url = "http://mouse ...

What is the best way to begin at a specific index in an array without skipping any elements?

As I continue my journey of learning JS, I have encountered a task that has left me quite perplexed. The objective is to provide an index to start from and also include the items missing in the array while displaying them in an angular format. Here is what ...

Having trouble storing radio buttons and checkboxes in MySQL database using AJAX

My app is facing an issue where radio buttons and checkboxes are not correctly entering information into the database. Currently, only text fields are successfully saving data, while checkboxes and radio buttons are only recording the value of the first ra ...

The PrimeNG FullCalendar feature seems to be malfunctioning and cannot be located

I've been working on integrating a FullCalendar module into my Angular 7 project. Despite following the steps provided in this link, I haven't had any luck: After executing this command: npm install <a href="/cdn-cgi/l/email-protection" clas ...

"Enhancing Hangman by updating the object-oriented array of values

I'm currently working on developing a hangman game using PHP and JS, but I've encountered some issues. In my project, there are two arrays involved - the answer array containing the correct letters and the user answer array storing the user' ...

Designing a Curved Stepper Component in the Shape of an S

I've been attempting to create a custom stepper component with an S-curve shape using React, but so far I haven't been successful. I even tried utilizing the MUI Stepper component and experimented with pure HTML and CSS, but couldn't achieve ...

Set a variable in Node.js to capture the return value of res.json

Embarking on the creation of a social network using Node.js, I must admit that I am quite new to this field. This marks my inaugural post on the subject and I sincerely hope for your understanding. Within my social network project, I aim to implement an a ...

Show various Bootstrap Alert Messages based on the type of error detected?

Trying to figure out how best to explain this, here it goes! I am working on a website and I want to incorporate alert messages. Check out some examples here. Depending on the form inputs, I need different alerts to be displayed. PHP will validate the in ...

Using jQuery to filter or duplicate options in a select box - a step-by-step guide!

I am struggling with filtering options in two select boxes. One contains projects and the other contains people: <select id="project"> <option data-person_ids="[75,76,77]">None</option> <option data-person_ids="[77]">Project A& ...

Retrieve information from deeply nested JSON and showcase using Vue-Multiselect

My goal is to fetch data from the server and present it in Multiselect using nested JSON, which can be done through Vue-Multiselect. Once displayed, I should have the ability to add new tags as needed, essentially updating the data. While I can display o ...

Safari's problem with CSS transitions

This issue is specific to Safari, as it has been tested and works fine in Chrome, Opera, and Firefox. Upon hovering over a certain div (1), a child div (2) slides out by adjusting the left property. However, the child elements (buttons) within the second ...

Console.log() will not display any JSON duplicates

My JSON data structure is pretty flat and can have duplicate attributes. I built a logic to remove the duplicates but when testing it out, something strange happened. The logic was always counting the attributes once, resulting in no duplicates. To test th ...