Reputation: 849
I want to create a simple loading bar with jQuery. I have n ajax requests that I run in sequence and I want to update the bar after each of them. The problem is that the HTML updates only when all of them are done. I can see the attribute changing as they load, but the visual changes appear only in the end. How can I make them appear during pageload?
I update bar width with this line progressDiv.attr('style', 'width: ' + perc + '%');
The width updates while loading, but the actual changes is only in the end.
Upvotes: 0
Views: 92
Reputation: 96
The correct syntax is
progressDiv.css('width', perc + '%');
or
progressDiv.css({width: perc + '%'});
Upvotes: 0
Reputation: 18997
Problem is that the browser engine will hold on to the CSS changes to the page untill the scripts are complete. This is a approach to have a better performance.
Why it happens?
For better understanding look at this example which changes the div
color in each line of the script. Observer the behaviour
$('div').css('background-color','red');
alert('now showing red!');
$('div').css('background-color','yellow');
alert('now showing yellow!');
$('div').css('background-color','green');
alert('now showing green!');
$('div').css('background-color','blue');
alert('now showing blue!');
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div style="width:100px;height:100px;"></div>
You can notice that the background color is not changed until the scripts are completed. This is because the browser engine keeps a track of all the changes happening on the element in its memory and once everything is complete it goes ahead and updates the UI, imagine if the browser had started updating the UI for every call? if there were many changes then you would see performance issue.
How to resolve it?
Look into this example
setTimeout(function(){
$('div').css('background-color','red');
alert('now showing red!');
},0);
setTimeout(function(){
$('div').css('background-color','yellow');
alert('now showing yellow!');
},0);
setTimeout(function(){
$('div').css('background-color','green');
alert('now showing green!');
},0);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div style="width:100px;height:100px;"></div>
So wrapping your functions inside a setTimeout
will resolve the issue.
That means wrapping your line progressDiv.attr('style', 'width: ' + perc + '%');
within a setTimeout
must fix your issue.
setTimeout(function(){
progressDiv.attr('style', 'width: ' + perc + '%');
},0)
To get more details on why this setTimeout(function(){},0)
works... Here is more detailed explanation
Hope this helps.
Upvotes: 1