0

i'm sorry to ask your help. I'm trying to get 3 functions in one, using array in Javascript.

Actually, I've this code to run loading bars for each language I'm trying to learn

function js() {
 var elem3 = document.getElementById("barone");   
 var width = 0;
 var id = setInterval(frame, 50);
 function frame() {
  if (width >= 20) {
    clearInterval(id);
  } else {
    width++; 
    elem3.style.width = width + '%'; 
    elem3.innerHTML = width * 1  + '%';
  }
 }
}
function php() {
  var elem4 = document.getElementById("bartwo");   
  var width = 0;
  var id = setInterval(frame, 50);
  function frame() {
    if (width >= 30) {
      clearInterval(id);
    } else {
    width++; 
    elem4.style.width = width + '%'; 
    elem4.innerHTML = width * 1  + '%';
   }
  }
 }
function sql() {
  var elem5 = document.getElementById("barthree");   
  var width = 0;
  var id = setInterval(frame, 50);
  function frame() {
    if (width >= 30) {
      clearInterval(id);
    } else {
      width++; 
      elem5.style.width = width + '%'; 
      elem5.innerHTML = width * 1  + '%';
    }
   }
  }

That's fine and it works well, but i'm trying to make an array for the div and the percent of loading bars

I've tried several times to shorten this code, and i'm actually stuck. This is the most (i think), closer to the answer:

var skillBar = ["barone","bartwo","barthree"];
var percentBar = [20, 30, 30];

function skill() {
  for (var j = 0; j < skillBar.length; j++) {
    var elem = document.getElementById(skillBar[j]);   
    console.log(skillBar[j]);
    console.log(percentBar[j]);
    var width = 0;
    var id = setInterval(frame, 50);
    function frame() {
      console.log(percentBar[j])  <--- This return undefined
      if (width >= percentBar[j]) {
        clearInterval(id);
      } else {
        width++; 
        elem.style.width = width + '%'; 
        elem.innerHTML = width * 1  + '%';
      }    
    }
  }
}  

but this doesn't work. The first two console.log works fine. It returns me the values in both arrays, but the third one returns me undefined, so the loading bar never ends. Worst, it only affect the last bar. First and 2nd doesn't load.

I know it's probably obvious for most of you, but I need a little help to make things work.

P.S : Sorry for my english, it's not my native language.

Emiya
  • 1
  • If I understand it correct, you want to animate the width of the bars? If that is the case, try to do it with CSS instead. Easier, smoother and much more performant. – Nicklas Wiborg Apr 15 '19 at 10:33
  • Nice, I take a look on this page https://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example, and now I'm more confused. Don't have any idea of what to do now. Thanks anyway. @NicklasWiborg Function skill() is trigger with onclick event in html (button). So Javascript was my first idea. – Emiya Apr 15 '19 at 11:18
  • In that case I would only use Javascript to toggle class on the elements and still take care of the animation in CSS. In this case I think you only need a css-transition and then change the width with JS once. I give you an example below. – Nicklas Wiborg Apr 16 '19 at 07:55
  • I made this fiddle: https://jsfiddle.net/ycv5f2t7/ – Nicklas Wiborg Apr 16 '19 at 08:10
  • Omg, you use just one fuction with id and width as parameters... That's clear code (I can understand it easily) and so synthtesed. Thanks and sorry for the time it took to you. – Emiya Apr 16 '19 at 08:41

1 Answers1

0

I think you need to take out fram function to outside of the function skill

var skillBar = ["barone","bartwo","barthree"];
var percentBar = [20, 30, 30];
var id;
function frame(j) {
      console.log(percentBar[j]) 
      if (width >= percentBar[j]) {
        clearInterval(id);
      } else {
        width++; 
        elem.style.width = width + '%'; 
        elem.innerHTML = width * 1  + '%';
      }    
    }
    
function skill() {
  for (var j = 0; j < skillBar.length; j++) {
    var elem = document.getElementById(skillBar[j]);   
    console.log(skillBar[j]);
    console.log(percentBar[j]);
    var width = 0;
    id = setInterval(frame(j), 50);
    
  }
}  
skill()
<div id="barone"></div>
<div id="bartwo"></div>
<div id="barthree"></div>
Andam
  • 2,087
  • 1
  • 8
  • 21