Leveraging the clearTimeout method to handle multiple occurrences of setTimeout

I have developed a unique twist on the classic Tic Tac Toe game called 'advanced' Tic Tac Toe. In this version, each move made by a player disappears after 10 seconds, returning the square to its original blank state. Everything works smoothly in the game, but there's a challenge when a user chooses to start a new game while canceling the current one.

If a player initiates a new game and clicks on a square that was previously occupied in the previous game, the timeout mechanism clears the square based on the previous game instead of waiting for the full 10 seconds as intended.

The issue lies in using clearTimeout to reset the timer only for the most recent instance of setTimeout - it doesn't account for multiple instances where squares were selected before resetting the game board. Since setTimeout is applied individually to each X and O within an onclick function, it becomes tricky to track multiple instance IDs.

Any insights or suggestions on how to address this issue would be greatly appreciated! See the code snippet below for reference.

UPDATE: A work-in-progress live demo of the game can be accessed here:

Global variables:

var elements = document.getElementsByClassName('cell');
var rows = document.getElementsByClassName('row');
var alternate = 0;
var counter = 0;
var timerX; // Manages setTimeout instances for 'X'
var timerO; // Manages setTimeout instances for 'O'

Function for setting X's and O's:

var play = function() {
for (i = 0; i < elements.length; i++) {
elements[i].onclick = function () {
if (this.className[0] == "c" && win == false) {
if (alternate % 2 == 0) {
this.className = "xmove";
alternate++;
counter++;
var paramPass = this;
timerX = setTimeout(function() {disappear(paramPass);}, 10000) // Maintains ID of the most recent setTimeout instance for 'X'
} else {
this.className = "omove";
alternate++;
counter++;
var paramPass = this;
timerO = setTimeout(function() {disappear(paramPass);}, 10000) // Maintains ID of the most recent setTimeout instance for 'O'
}
}
position(this);
analysis();
}
}
}

Reset function triggered by user selecting 'New Game':

var reset = function() {
header[0].innerHTML = "Tic Tac Toe";
for (i = 0; i < rows.length; i++) {
for (j = 1; j < 6; j += 2) {
rows[i].childNodes[j].className = "cell animated bounceIn";
}
}
clearTimeout(timerX); // Clears Timeout for the most recent instance (last 'X' clicked) before the game was reset
clearTimeout(timerO); // Clears Timeout for the most recent instance (last 'O' clicked) before the game was reset
board = [["","",""],["","",""],["","",""]];
counter = 0;
alternate = 0;
win = false;
}

Answer №1

One effective strategy is to maintain a list of pending timeouts. Each timeout will automatically remove itself from the list once it has triggered. To reset, simply loop through the list and clear all remaining timeouts using clearTimeout.

A possible implementation could look like this:

var pending = {};
function customSetTimeout(callback, delay) {
  var timer;
  timer = setTimeout(function() {delete pending[timer]; callback();}, delay);
  pending[timer] = 1;
}
function clearAllTimeouts() {
  for (var timer in pending) {
    if (pending.hasOwnProperty(timer)) {
      clearTimeout(timer);
      delete pending[timer];
    }
  }
}

Answer №2

An efficient method is to establish a collection of timer IDs and then clear them by looping through the array using clearTimeout for each one. You can conveniently add new IDs to the array by utilizing Array.push.

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

Issue with radio button list not functioning properly in Mozilla and Chrome browsers

My web application has a radiobuttonlist with an onclick event. It functions properly in IE, but not in some other browsers. Here is a snippet of the code: <asp:RadioButtonList ID="rbgThreadStatus" runat="server" RepeatDirection=&quo ...

Numerous input fields available for AJAX auto-complete functionality and name verification

Currently, I am working on implementing a text box that will search through a mysql database and display auto-completed text below the input field. Additionally, I want to include a visual indicator like a confirmation tick or cross to signify whether the ...

Executing a for loop with a parameter passed into the setTimeout function

Help Needed with AJAX Request Timeout Issue I recently created an array and tried to send an ajax request using setTimeout. However, I encountered a problem where I couldn't get the parameter in setTimeout. The console log showed that the variable &a ...

How to change the color of the tooltip text in Bootstrap Vue

In an attempt to modify the color of the tooltip text from its default to red https://i.sstatic.net/fF78X.png Any payment made during the night hours (00:00 – 06:00) must be displayed as red. ...

Converting date formats using AngularJS

After clicking the search button and the radio button, I am converting the date format. Everything works fine when I search by date, but I encounter a problem when I click the radio button. HTML Code <form action="{{URL::current()}}" ng-submit="submit ...

Is there a way to create triangles on all four corners of an image using canvas in JavaScript?

In my code, I am currently working on drawing rectangles on the corners of an image using JavaScript. To achieve this, I first extract the image data from a canvas element. // Get image data let imgData = ctx.getImageData(0, 0, canvas.width, canvas.height) ...

What is the best way to initiate a Bootstrap carousel so that it begins with the first image every time a modal window appears

I am in the process of creating my own portfolio to showcase my work. I have implemented a feature where clicking on an image opens up a Bootstrap carousel. However, I'm facing an issue where the carousel doesn't always start with the first imag ...

Javascript detecting key press event only firing once when a key is continuously held down

I have implemented the code below to redirect to a specific page when the w, s, a, d keys are pressed. <script> document.addEventListener('keydown', function(e){ e = e || window.event; key = e.keyCode || e.charCode; var keys = { 87: &ap ...

Get the value of a function that was previously assigned to an onclick event using JavaScript

Here is the code snippet I am currently working with: document.getElementById(myid).onclick = function() { HandleGPIO(val1, val2); }; if (console) { console.log(document.getElementById(myid).getAttribute('onclick')); } My goal is to de ...

What is the best way to clear an array?

Yesterday I had a query regarding JSON Check out this link for details: How to return an array from jQuery ajax success function and use it in a loop? One of the suggested answers included this script: setInterval(updateTimestamps,30000); var ids = new ...

Utilize Material UI AutoComplete in React to showcase a variety of choices in a list and capture various selections in the form state, including multiple values

I'm looking to implement Autocomplete in a way that it saves a specific property of an object in the form state and displays a different property in the autocomplete options list. For instance, if we have the following option list: [ { gender_name ...

Experiencing difficulties when trying to pan and zoom the data obtained from d3.json within a line chart

I am currently working on developing a trend component that can zoom and pan into data fetched using d3.json. Here is the code I have written so far: <script> var margin = { top: 20, right: 80, bottom: 20, left: 50 }, width = $("#trendc ...

Implement a button transformation upon successful completion of a MySQLi update using AJAX

When displaying multiple database results with buttons that can be turned on or off inside a div, I am looking to implement AJAX to toggle the button state between ON and OFF upon clicking, and then update the button without refreshing or reloading the ent ...

Upon the completion of the page loading, the function will be called immediately after the controller has provided the

I am facing an issue where I am trying to call a computed property upon page creation, but it is giving an error stating that it cannot read the data for 'undefined'. This is because the data I require is not fully loaded yet. However, when I del ...

Creating a TextGeometry in THREE JS that Reacts to Mouse Movements

I have created a unique source code where the text rotates based on mouse position. // Setting up the scene const scene = new THREE.Scene(); let camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 ) ...

Encountering issues with retrieving a specific document from DocumentDB in Node.js

My goal is to retrieve a specific document from DocumentDB using the document ID. The collection consists of four fields, with author serving as the partition key. { "id": string, "author": string, "title": string, "year": int } I have implemente ...

Transfer Parameters from the Screen to the Header Component in React Navigation

I am facing an issue where I am unable to pass a function as parameter to the header component in react-navigation v5. In the code snippet provided below in filtersscreen.js, my intention is to pass savefilters to headerRight which is located in navigatio ...

Node.js and react-create-app are not compatible with each other

I am currently using node.js version 14.6.0 and node-v version 7.20.0 To replicate the issue, follow these steps: npx create-react-app my-app2 Once everything is installed, run npm i After completing the above steps, you may encounter the following warn ...

Guide to importing an npm package into a client-side file

Having some trouble importing the js-search npm package into my client-side .js file. The documentation suggests using import * as JsSearch from 'js-search';, but I keep getting a Uncaught TypeError: Failed to resolve module specifier "js-se ...

What is the best way to obtain the full URL in a live environment?

I'm currently encountering an issue where I am unable to obtain the absolute URL in the production build when using getStaticPaths and getStaticProps. export async function getStaticPaths() { const url = process.env.NODE_ENV === "developmen ...