Sai*_*eep 17 javascript css jquery settimeout twitter-bootstrap
我正在动态更新setTimeout()
函数后的一些元素.jQuery函数.text()
似乎在处理时随着数组索引的每次更改而动态更新.但是一个正在改变的引导进度条似乎.css()
并.attr()
没有动态更新.这是我的页面:http://imdbnator.com/process.php?id = f144caf0843490c0d3674113b03da0c5&redirect = false
您可以看到文本已更改但进度条仅在整个setTimeout()
函数完成后结束.另外,如果我设置了delay = 1000
.有用.但它因应用而变慢.因此,我需要delay = 0
.但为什么进度条不会改变?
这是我的片段
function launch(a) {
var inc = 0;
var maxc = a.length;
var delay = 0; // delay milliseconds
var iID = setInterval(function () {
var index = inc;
var movie = a[inc];
//start processing function
//styling while processing
var markerPer = ((index + 1) / rawListNum) * 100; // marker percentage
$("#procNum").text("(" + (index + 1) + "/" + rawListNum + ")"); //Processing number
$("#procMovie").text(movie); //Processing Name
$("div[role='progressbar']").css("width", markerPer + "%").attr("aria-valuenow", markerPer); // progress bar -> DOES NOT WORK
if (++inc >= maxc) clearInterval(iID);
},
delay);
}
Run Code Online (Sandbox Code Playgroud)
Kyl*_*Mit 10
作为解释,很多答案都会指出大多数浏览器在UI线程上运行JavaScript的事实,因此在执行JavaScript时它们无法更新界面.相反,浏览器将等待Javascript完成并将控制权返回给UI线程.
虽然记住这一点非常重要,但它并没有为您的代码发挥作用.如果您正在更新进度条,请执行以下操作:
for (i = 0; i < len; i++) {
updateProgressBar(i)
};
Run Code Online (Sandbox Code Playgroud)
然后它肯定会阻止UI更新直到结束.
但是你已经通过使用setTimeout
或者做了正确的事情setInterval
,它们在代码中有异步回调.这意味着JavaScript能够暂停足够长的时间来管理任何UI消息.事实证明文本能够动态更新.
正如您的问题所问,为什么,如果UI正在更新,进度条也不会更新?
答案在于Bootstrap将以下CSS应用于进度条:
.progress-bar {
-webkit-transition: width .6s ease;
-o-transition: width .6s ease;
transition: width .6s ease;
}
Run Code Online (Sandbox Code Playgroud)
当调用之间的延迟为0毫秒时,浏览器确实有时间更新UI,但没有时间完成600毫秒的CSS转换.因此,直到最后才能看到动画.
正如OhAuth指出的那样,您可以通过使用CSS删除过渡效果来阻止浏览器延迟宽度更新:
.progress .progress-bar {
-webkit-transition: none;
-o-transition: none;
transition: none;
}
Run Code Online (Sandbox Code Playgroud)
如果您循环遍历大量项目,增量更新将提供某种动画.如果您想留下通用用例的样式,可以在代码中关闭和打开转换.从jQuery 1.8开始,您可以在没有供应商前缀的情况下更新CSS属性,因此您只需要调用即可.css("transition","none")
.
当然,根据您为每部电影所做的工作量,JavaScript可以在您可以直观地检测所有UI更改之前完成,在这种情况下延长延迟不会受到影响.如果您想测试运行时间较长的进程,可以使用以下睡眠功能:
function sleep(sleepyTime) {
var start = +new Date;
while (+new Date - start < sleepyTime){}
}
Run Code Online (Sandbox Code Playgroud)
这是一个你可以玩的演示,每个设置都是一个变量,你可以配置它来看看它会如何反应,但最好的办法就是有条件地删除过渡.
var delay, numMovies, throttledMovies, sleepTime, removeTransition;
$("#delay").change(function(){ delay = this.value }).change()
$("#movies").change(function(){ numMovies = this.value }).change()
$("#sleep").change(function(){ sleepTime = this.value }).change()
$("#transition").change(function(){ removeTransition = this.checked }).change()
$("#loadMovies").click(loadMovies);
function loadMovies() {
var i = 0;
throttledMovies = Movies.slice(0, numMovies)
if (removeTransition) {
$('#progress-bar-movie').css("transition","none");
}
var interval = setInterval(function () {
loadMovie(i)
if (++i >= numMovies) {
clearInterval(interval);
$('#progress-bar-movie').css("transition","width .6s ease");
}
}, delay);
};
function loadMovie(i) {
var movie = throttledMovies[i];
var percentComplete = ((i + 1) / numMovies) * 100;
sleep(sleepTime);
// update text
$("#procNum").text("(" + (i + 1) + "/" + numMovies + ")");
$("#procMovie").text(movie.Title);
// update progress bar
$('#progress-bar-movie')
.css('width', percentComplete+'%')
.attr('aria-valuenow', percentComplete);
};
function sleep(sleepyTime) {
var start = +new Date;
while (+new Date - start < sleepyTime){}
}
Run Code Online (Sandbox Code Playgroud)
<link href="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.2/css/bootstrap.css" rel="stylesheet"/>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.2/js/bootstrap.js"></script>
<script src="http://kylemitofsky.com/libraries/libraries/movies.js"></script>
<!-- params -->
<label for="delay">Delay (ms)</label>
<input type="number" value="0" min=0 max=1000 id="delay"/>
<label for="movies"># Movies </label>
<input type="number" value="250" min=0 max=250 id="movies"/>
<label for="sleep">Sleep time (ms)</label>
<input type="number" value="0" min=0 max=1000 id="sleep"/>
<label for="transition">Remove transition? </label>
<input type="checkbox" checked="true" id="transition"/><br/><br/>
<button class="btn btn-primary btn-lg" id="loadMovies">
Load Movies
</button><br/><br/>
<p>
<b>Current Title</b>: <span id="procMovie"></span><br/>
<b>Progress</b>: <span id="procNum"></span>
</p>
<div class="progress">
<div class="progress-bar" role="progressbar" id="progress-bar-movie"
aria-valuenow="0" aria-valuemin="0" aria-valuemax="100"></div>
</div>
Run Code Online (Sandbox Code Playgroud)