Tips for dynamically creating an HTMLElement and updating innerHTML with the help of window.setInterval

I wrote the following script for a countdown clock. My goal was to dynamically create HTMLElement (span) and update innerHTML using window.setInterval. However, I am facing an issue with updating the current date without creating a new group of spans.

Here is my code:

var CustomCountdown;
(function (CustomCountdown) {
    var Countdown = (function () {
        function Countdown(id, endDate, message) {
            this.id = id;
            this.endDate = endDate;
            this.message = message;
        }
        Countdown.appendChildElement = function (DOMNode, tagName) {
            var child = document.createElement(tagName);
            DOMNode.appendChild(child);
            return child;
        };
        Countdown.prototype.getTimeRemaining = function (enddate) {
            var t = Date.parse(enddate) - Date.parse(new Date().toString());
            var seconds = Math.floor((t / 1000) % 60);
            var minutes = Math.floor((t / 1000 / 60) % 60);
            var hours = Math.floor((t / (1000 * 60 * 60)) % 24);
            var days = Math.floor(t / (1000 * 60 * 60 * 24));
            return {
                'total': t,
                'days': days,
                'hours': hours,
                'minutes': minutes,
                'seconds': seconds
            };
        };
        Countdown.prototype.drawCountdown = function (id, enddate) {
            var container = document.getElementById(id);
            var timeRemaining = this.getTimeRemaining(enddate);
            var update = function () {
                for (var key in timeRemaining) {
                    if (timeRemaining.hasOwnProperty(key)) {
                        var span = Countdown.appendChildElement(container, 'span');
                        span.setAttribute('class', key);
                        span.innerHTML = timeRemaining[key];
                    }
                }
            };
            return update();
        };
        Countdown.prototype.initialize = function () {
            var that = this;
            this.drawCountdown(that.id, that.endDate);
            var update = setInterval((function () {
                that.drawCountdown(that.id, that.endDate);
            }), 1000);
        };
        return Countdown;
    })();
    CustomCountdown.Countdown = Countdown;
})(CustomCountdown || (CustomCountdown = {}));

Check out the demo on jsfiddle

Answer №1

Develop a function that eliminates the previous span element

https://jsfiddle.net/7vjf4y5u/1/

I included the following function to CountdownTimer prototype

/* Implement a method to eliminate the old span*/
Countdown.prototype.removeSpan = function(){
    if(this.span){
        this.span.remove();
  }
};

Then, I modified the function below to execute it after generating the new span

Countdown.prototype.drawCountdown = function(id, enddate) {
  var self = this; //Added this for referencing in the update function
  var container = document.getElementById(id);
  var timeRemaining = this.getTimeRemaining(enddate);
  var update = function() {
    for (var key in timeRemaining) {
      if (timeRemaining.hasOwnProperty(key)) {
        var span = Countdown.appendChildElement(container, 'span');
        span.setAttribute('class', key);
        span.innerHTML = timeRemaining[key];
        self.removeSpan(); //Discard the old span
        self.span = span; //Establish the new span
      }
    }
  };
  return update();
};

If you prefer not to create a new span each time, simply maintain a reference to the span and modify its innerHTML as needed

https://jsfiddle.net/s3yzLvee/1/

Countdown.prototype.drawCountdown = function(id, enddate) {
  var self = this;
  var container = document.getElementById(id);
  var timeRemaining = this.getTimeRemaining(enddate);
  var update = function() {
    for (var key in timeRemaining) {
      if (timeRemaining.hasOwnProperty(key)) {
        /* Keep track of the span by setting a reference*/
        if(!self.span){
            self.span = Countdown.appendChildElement(container, 'span');
        }

        //Work on the referenced span
        self.span.setAttribute('class', key);
        self.span.innerHTML = timeRemaining[key];
      }
    }
  };
  return update();
};

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

The attempt to access 'reading params' is resulting in an error due to undefined properties

Looking for some assistance in resolving an error I'm encountering. Below is a snippet of my code: const ProductScreen = ({match, history}) => { const [qty, setQty] = useState(1); const dispatch = useDispatch(); const productDetail ...

What is the best way to show the current value of a checkbox element in the future?

I want to add multiple checkboxes using this method: $(".btn-sample").on("click", function() { $(".container").append( '<input class="check-sample" type="checkbox" value="'+check_value+'"/>' ); }); The issue I' ...

Does the arc() method in canvas.getContext('2d') appear centered?

It caught my attention that circles do not require any offsetting to be centered. Is this automatic? If so, can you explain why it differs from the rect, fillRect, fillText, and strokeText methods where centering requires offsetting? ...

Typescript is throwing a fit over namespaces

My development environment consists of node v6.8.0, TypeScript v2.0.3, gulp v3.9.1, and gulp-typescript v3.0.2. However, I encounter an error when building with gulp. Below is the code snippet that is causing the issue: /// <reference path="../_all.d. ...

Keep a vigilant eye on the peak utilization of memory within the Node.js process

I am in search of a way to effectively monitor the maximum memory usage in a Node.js process, regardless of whether there are memory leaks or not. The processes in question include both real applications and synthetic tests. My expectation is that it sho ...

How can I manually trigger the rendering of a dynamic component in Vue 3?

Is there a way to ensure that all dynamic components are rendered at once? Currently, only the component of the last tab is getting mounted. I want to mount them all at the same time. const addTab = (symbol: string) => { const id = nextTabId++; tab ...

PWA notifications not working on iOS with FCM even after multiple tries

I am currently utilizing Firebase Cloud Messaging in order to send daily notifications to iOS users who have installed a PWA app. Upon testing, I noticed that each token is limited to receiving only 2 notifications successfully. Any attempt beyond that w ...

Contrast in output between for and for..of loops demonstrated in an example

Here are two code snippets, one using a traditional for loop and the other using a for...of loop. export function reverseWordsWithTraditionalForLoop(words: string): string { const singleWords: string[] = words.split(' '); for (let i = 0; i &l ...

Add a new value to the translation token using ng-bind

I'm attempting to loop through an element 5 times using ng-repeat and track by $index. Following that, I aim to utilize the value from $index to supplement a translation token. This appended index value corresponds with the token which retrieves the a ...

The ng-change and onchange events are not functioning as expected for the input field with the type "file"

<button ng-click="controller.foo()">Click<button> is functioning properly. However, <input type="file" ng-model="logo" onchange="controller.foo()"> seems to be malfunctioning. Additionally, <input type="file" ng-model="logo" ng-ch ...

The class member was not defined in the asynchronous callback

Let's consider this code snippet: import request = require("request"); class CFoo { test:number; async getItem(): Promise<number> { var requestOptions = { method: 'GET', url: `https://www.goog ...

Create a JavaScript function to generate a random number every few seconds

Is there a way to quickly generate a fresh random number every second using the Math.random() method? I attempted placing it within a function and returning Math.random, but it keeps generating the same number. Are there any concise approaches to accompl ...

Creating PDFs with Vue.js from HTML sources

Looking for a way to generate PDFs and insert variable values in specific locations for an order confirmation on my website. Planning to store the generated PDFs on Firebase Storage. Any suggestions on libraries or methods to achieve this? Is it possible ...

What is the process for converting strings or text to EBCDIC using JavaScript?

In the midst of developing a website, I am working on a feature that allows users to input a minimum of 256 characters/strings (with code verification), choose between ASCII or EBCDIC conversion, and view the converted text string displayed on the page bas ...

Determine the presence of an HTML data attribute within any of the parent elements

I am attempting to locate an HTML data attribute on one of the ancestors of a given element, baseElement, and retrieve its value if found. In the case where the attribute is present in multiple ancestors, I am interested in the one closest to baseElement. ...

Utilizing Node.js to Retrieve Data from MySQL

Hi there, I'm new to NodeJS and I'm curious about how to fetch a MySQL query like we do in PHP. $query = mysql_query("SELECT * FROM accounts"); while($fetch = mysql_fetch_array($query)) { echo $fetch['Username']; } How would this be ...

Caution: Prop type validation failed: The `open` prop in `ForwardRef(Modal)` is designated as required, yet its value is currently `undefined`

After implementing code from Material UI Dialog component, I am receiving a warning. Although the application functions properly, I am seeking a solution to resolve this warning. Can anyone provide guidance on how to address it? To access the Material UI ...

Use jQuery to add a class when a specific element is clicked and then remove that class when another element

Currently, I am working on creating a photo frame designer. One of the features I am trying to implement is that when a pattern is clicked, it fills the text with that pattern. I have managed to do this using the .addClass function. However, I have run int ...

JavaScript and Ajax are having trouble loading some controls upon document load

This is quite perplexing, but let me try to summarize. I have two sets of JavaScript code that utilize AJAX, JSON, PHP, and more to fetch specific data and load a series of controls. In one scenario, when triggered by a click event handler, all the control ...

Create an input field with a dynamic and exclusive identifier using the DataTables plugin

I am having trouble creating unique IDs for each input field based on the number of rows Here is the code snippet: $(document).ready(function() { var oTable = $('#jsontable').dataTable(); //Initialize the datatable $.ajax({ url ...