0

How to get rid of the wired [].forEach.call(counters, function(counter) {... part or pass argument to it to update the counter?

The code has a function inside of the [].forEach.call(... that sets the new value to the counter named setValue(currentValue);. I can't figure out a way to access the setValue() and pass new arguments...

I want to use a normal function to update the value by passing argument like :

function update(newValue){
// everything goes here
};

And here is the original code (of course you need to only modify the JS!), in this code I've used setTimeout to update the counter:

let counters = document.getElementsByClassName('number-ticker');

let defaultDigitNode = document.createElement('div');
defaultDigitNode.classList.add('digit');

for (let i = 0; i < 11; i++) {
  defaultDigitNode.innerHTML += i + '<br>';
}




[].forEach.call(counters, function(counter) {
  
  let d = defaultDigitNode.cloneNode(true);
  let digit = counter.appendChild(d);
  let currentValue = 10; //set initiale value
  setValue(currentValue);
  
  //update the value
  setTimeout(function(){
  setValue(9);
  }, 1000)

  function setValue(number) {
    digit.style.marginTop = '-' + number + 'em';
  }
});
:root {
  background-color: #555;
  color: white;
  font-size: 25vh;
  font-family: Roboto Light;
}

body,
html {
  margin: 0;
  height: 100%;
}

.container {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100%;
}

.number-ticker {
  overflow: hidden;
  height: 1em;
  background-color: #333;
  box-shadow: 0 0 0.05em black inset;
}

.number-ticker .digit {
  float: left;
  line-height: 1;
  transition: margin-top 1.75s ease;
  border-right: 1px solid #555;
  padding: 0 0.075em;
  text-align: center;
}
<!doctype html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <title>Number Ticker</title>
        <meta name="viewport" content="width=device-width,initial-scale=1">
        <link rel="stylesheet" href="number-ticker.css">
    </head>
    <body>
        <div class="container">
            <div class="number-ticker" data-value="10"></div>
        </div>

        <script src="number-ticker.js"></script>
    </body>
</html>

We can only update and pass an argument to setValue inside the [].forEach.call() in the code. What if we want to update the setValue outside of the [].forEach.call()

Sara Ree
  • 3,417
  • 12
  • 48
  • 1
    Can you explain what you are trying to acheive with `[].forEach.call` ? – Nicolas Nov 11 '19 at 16:12
  • I was hoping that you could tell me :) – Sara Ree Nov 11 '19 at 16:15
  • I've found my answer to the [`[].forEach.call` here](https://stackoverflow.com/a/16053436/5784924) From what i understand it's a easier way to call `Array.prototype.forEach.call`, and it passes `counters` as a value to the `forEach` function. It does that because `getElementsByClassName` does not have a `forEach` method nativaly but will work with one. – Nicolas Nov 11 '19 at 16:19
  • What is the question here exactly? It's a bit unclear – adiga Nov 11 '19 at 16:20
  • @adiga We can only update and pass an argument to `setValue` inside the `[].forEach.call()` in the code. What if we want to update the `setValue` outside of the `[].forEach.call()` – Sara Ree Nov 11 '19 at 16:24

1 Answers1

1

I think you're over-engineering your solution, this is my suggestion:

I'm using Array.from and Array.keys to generate an array and doing a for loop on it. In my for loop, I'm running setTimeout to update my counter.

function setValue(number) {
  let digit = document.getElementsByClassName('digit')[0];
  digit.innerHTML = number;
}

const currentValue = 10;

Array.from(Array(currentValue).keys()).reverse().forEach(function(number,index) {
    setTimeout(function(){
        setValue(number + 1, index);
    }, index * 1000);
});
:root {
  background-color: #555;
  color: white;
  font-size: 25vh;
  font-family: Roboto Light;
}

body,
html {
  margin: 0;
  height: 100%;
}

.container {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100%;
}

.number-ticker {
  overflow: hidden;
  height: 1em;
  background-color: #333;
  box-shadow: 0 0 0.05em black inset;
}

.number-ticker .digit {
  float: left;
  line-height: 1;
  transition: margin-top 1.75s ease;
  border-right: 1px solid #555;
  padding: 0 0.075em;
  text-align: center;
}
<!doctype html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <title>Number Ticker</title>
        <meta name="viewport" content="width=device-width,initial-scale=1">
        <link rel="stylesheet" href="number-ticker.css">
    </head>
    <body>
        <div class="container">
            <div class="number-ticker" data-value="10">
              <div class="digit"></div>
            </div>
        </div>

        <script src="number-ticker.js"></script>
    </body>
</html>

Hope this is helpful!

Avanthika
  • 3,984
  • 1
  • 12
  • 19