Reputation: 3
I have a progress bar that I want to update whenever a user clicks on something. So it is possible to go backwards and forwards through the progress bar.
Currently, the bar seems to work, but the bar is flickering, as if the bar is being loaded every second. For eg, the user is at 70%, so the bar will fill up to there, then it clears, then it fills up to 70% again. However, this is happening hundreds of time per second, so it seems like the bar is flashing. I also dont know if what I said above is correct - I dont know if it is actually filling then clearing, filling then clearing x100. All I know is thats what it looks like, and its giving it a flickering effect.
I got the code from here: https://www.w3schools.com/howto/howto_js_progressbar.asp
and I am using the first eg, with no label.
I have amended it so that it takes an input and the bar is based on that.
function move(i) {
var elem = document.getElementById("myBar");
var width = 1;
var id = setInterval(frame, 10);
function frame() {
if (width >= 100) {
clearInterval(id);
} else {
width= (i/lengthOfCurrentModule)*100;
elem.style.width = width + '%';
}
}
}
In the example it was
width++;
so I changed it to what I wanted it to do.
I tried to get rid of
if (width >= 100) {
clearInterval(id);
}
bc I thought it might have been calculating it was over 100, but the problem persists.
I dont know why its flickering like that. Any help is appreciated
Upvotes: 0
Views: 2478
Reputation: 2038
I had the same problem. The progress bar was reporting progress for a compute-intensive process. I found that inserting a 500ms wait after I changed the progress value, and prior to executing the next compute-intensive step in my process, allowed the view to render smoothly.
Code snippet:
let count = 0;
for (const name of names) {
count ++;
this.progressLabel = name;
this.progressValue = count / names.length;
await sleep(500); // give a chance for the view to update
await computeIntensiveStuff(name);
}
<ion-item>
<ion-label position="stacked">
Adding: {{progressLabel}}
</ion-label>
<ion-progress-bar [value]="progressValue">
</ion-progress-bar>
</ion-item>
Upvotes: 0
Reputation: 324690
Broadly speaking, if you can use CSS to animate something, then you should. This allows the browser to fine-tune control, accounting for things like mobile device computing power, battery and so on. This also automatically includes things like delta-timing to ensure that the animation takes the correct amount of time no matter what.
function move() {
var elem = document.getElementById("myBar");
var perc = +document.getElementById("percentage").value;
// optional: ensures the bar fills/empties at the same rate by varying the animation duration
var previous = move.previous || 0;
move.previous = perc;
var change = Math.abs(perc - previous);
elem.style.transitionDuration = (change*10)+"ms";
elem.style.width = perc+"%";
}
#myProgress {
width: 100%;
background-color: grey;
overflow: hidden;
}
#myBar {
width: 0%;
height: 30px;
background-color: green;
transition: width 500ms linear;
}
<div id="myProgress">
<div id="myBar"></div>
</div>
<input type="number" min="0" max="100" id="percentage">
<button onclick="move()">Click Me</button>
Upvotes: 1
Reputation: 1737
Is this what you wanted to achieve? You can enter a value and the progressbar fills up to that value.no logic implemented so please enter a value between 1 and 100 and click the button.
function move() {
var elem = document.getElementById("myBar");
var perc = document.getElementById("percentage").value;
var width = 1;
var id = setInterval(frame, 10);
function frame() {
if (width >= perc) {
clearInterval(id);
} else {
width++;
elem.style.width = width + '%';
}
}
}
#myProgress {
width: 100%;
background-color: grey;
}
#myBar {
width: 1%;
height: 30px;
background-color: green;
}
<div id="myProgress">
<div id="myBar"></div>
</div>
<input type="number" id="percentage">
<button onclick="move()">Click Me</button>
Upvotes: 0