0

My Set Up

I have a pie chart css that I use to display pie charts in percentage,

The class works this way:
<div id="chart" class="c100 p20 small dark center">

The second class "p20" means it should display a chart of 20%, thus if i change it to "p70", is shows a 70% chart.

Now I have also a Java Script code to generate a random number and display it in a div,

setInterval(function() {
    var random = (Math.floor((Math.random() * 100) + 1));
    document.getElementById("demo").innerHTML = random;
}, 1000);

It works

What I want

But i also want the random number to change the class of the chart div, such as

  • if the random number is 30, then the class of the chart changes to p30

    <div id="chart" class="c100 p30 small dark center"> ,

    if the random number is 80, then the class of the chart changes to p80

    <div id="chart" class="c100 p80 small dark center">

I've tried this, but it doesn't work, it only updates with the first random number and stops.

 setInterval(function() {
     var random = (Math.floor((Math.random() * 100) + 1));
     document.getElementById("demo").innerHTML = random;
     //remove the default class and add the new class
     document.getElementById("chart").classList.remove('p20');
     document.getElementById("chart").classList.add('p' + random);
 }, 1000);
5
  • Are you really going to create a css selector for 100 different classes? Commented Apr 5, 2018 at 16:38
  • 2
    You need to keep track of the old number to remove the associated classname correctly. Nor is there a variable ran declared in your code, did you mean 'p' + random? Commented Apr 5, 2018 at 16:38
  • document.getElementById("chart").classList.remove('p20'); This will do nothing if after the first time you add something like p50. Commented Apr 5, 2018 at 16:38
  • @JaredSmith I'v changed it to random, i'm glad you understand the problem, so how do i keep track of the previous random number? or maybe i could always change the second class to the new random number no matter the previous number Commented Apr 5, 2018 at 16:41
  • @staynjokede see my answer. Commented Apr 5, 2018 at 16:48

3 Answers 3

4

Declaring a previousRandom variable outeside of current scope (globally, so to speak), will allow you to keep track of the random value generated in the last interval.

var previousRandom;
setInterval(function() {
  var random = (Math.floor((Math.random() * 100) + 1));
  document.getElementById("demo").innerHTML = random;
  //remove the previous (random) class and add the new (random) class
  document.getElementById("chart").classList.remove(previousRandom ? ('p' + previousRandom) : false);
  document.getElementById("chart").classList.add('p' + random);
  previousRandom = random;
}, 1000);

This way we can generate a new random value, add it to the element and in the next interval we will remove the previous random value.

Sign up to request clarification or add additional context in comments.

6 Comments

I have no idea why I keep getting this Uncaught DOMException: Failed to execute 'remove' on 'DOMTokenList': The token provided must not be empty.
My bad, check the edit in a second. The problem is that .remove does not allow an empty string (which happens on the very first iteration when there was no previousRandom value).
Uncaught TypeError: Cannot set property 'innerHTML' of null
That means your DOM isn't loaded properly yet (The element with the id demo does not exist yet, so getElementById('demo') returns null, which in return has no method .innerHtml. Either put your entire <script>-tag right in front of </body> or wrap the entire code provided in a window.onload = function() { ... the code provided in my answer ... } function. This way the JS will get executed when the DOM was fully loaded.
Just out curiosity, is there any way of keeping the previousRandom orderly in an array so I could use them to plot a graph or something.?
|
3

To remove the previous class you have to know which class was there previously, to get it I stored it in the prevClass attribute.

setInterval(function() {
     var random = (Math.floor((Math.random() * 100) + 1));
     var ele = document.getElementById("chart");
     ele.innerHTML = random;
     //remove the default class and add the new class
     var prev = ele.getAttribute("prevClass");
     ele.classList.remove(prev||"");
     ele.classList.add('p' + random);
     ele.setAttribute("prevClass",'p' + random);
 }, 1000);

Comments

1

Generally speaking, you'll want to keep the last class in a closure:

setInterval((function() {
  var last = 0;
  var element = document.getElementById('chart');
  // this is the function that will actually be run by setInterval
  // and it has access to last and element
  return function () {
    element.classList.remove('p' + last);
    last = Math.random() * 100 | 0; // binary or with 0 truncates to int
    element.innerHTML = last;
    element.classList.add('p' + last);
  };
})(), 1000); // note the invocation here that returns the inner function

2 Comments

I keep getting Uncaught TypeError: Cannot read property 'classList' of null
@staynjokede then there's no element with an id of chart in the DOM at that time. Make sure this code executes after the DOM is ready (you should always do that anyways).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.