Javascript 为什么';与文本不同,进度条是否会动态变化?

Javascript 为什么';与文本不同,进度条是否会动态变化?,javascript,jquery,css,twitter-bootstrap,settimeout,Javascript,Jquery,Css,Twitter Bootstrap,Settimeout,我在使用setTimeout()函数后动态更新了一些元素。jQuery函数.text()似乎在处理过程中随着数组索引的每次更改而动态更新。但是通过.css()和.attr()更改的引导进程栏似乎没有动态更新。这是我的页面: 您可以看到文本已更改,但进度条仅在整个setTimeout()函数完成后才完成。另外,如果我将延迟设置为1000。它起作用了。但应用程序会减慢速度。因此,我需要delay=0。但是为什么progressbar没有改变呢 这是我的片段 function launch(a) {

我在使用
setTimeout()
函数后动态更新了一些元素。jQuery函数
.text()
似乎在处理过程中随着数组索引的每次更改而动态更新。但是通过
.css()
.attr()
更改的引导进程栏似乎没有动态更新。这是我的页面:

您可以看到文本已更改,但进度条仅在整个
setTimeout()函数完成后才完成。另外,如果我将
延迟设置为1000
。它起作用了。但应用程序会减慢速度。因此,我需要
delay=0
。但是为什么progressbar没有改变呢

这是我的片段

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);
}

这是由于引导程序设置进度条状态更改动画的方式。如果超时时间间隔小于动画时间,它将对重画进行排队

尝试将此添加到进度栏的CSS中:

-webkit-transition: none;
transition: none;
另一个解决方法():


如果必须保留动画,可以使用保守的间隔延迟,例如100毫秒。用户不应该注意到的延迟。

如果您真的需要将计算延迟设置为零,那么我会将计算和进度条值的设置分开,以便您在一个
设置间隔中计算该值,然后运行一个单独的
setInterval
,每隔100毫秒将该条更新到此值

这样,您的计算是最新的,您的UI也有时间进行更新

如果你想用同样的方法处理这两个问题,那么我认为你需要增加至少100毫秒的延迟

例如:

Javascript:

var _ValueToSet = 0;
$(document).ready(function () {

    // SET VALUE EXTREMELY FAST (your current code)
     setInterval(function () {
        _ValueToSet = Math.round(Math.random() * 100); // get value we are going to set
    }
    , 0); // run as fast as possible

    // RUN UI UPDATE AT 100MS (separate thread for ui updates).
    setInterval(function () {
        setRandom()
    }
    , 100); // give ui 100ms to do its thing
});

function setRandom() {
    var elem = $('.progress-bar'); // what is our target progress bar

    // set both style width and aria-valuenow
    elem.css('width', _ValueToSet + '%');
    elem.attr('aria-valuenow', _ValueToSet);
}
HTML:


这可能是一个重新起草的问题。由于延迟设置为0,CSS更改直到最后一次更新才绘制

强制重画的最简单方法是读取元素高度:

$("div[role='progressbar']").css("width", markerPer + "%").attr("aria-valuenow", markerPer);
$("div[role='progressbar']").height();

文本和进度条会动态更改,但使用
delay==0
速度非常快:():

HTML:

<div class="text">Text</div>
<div class="progress">
    <div class="progress-bar" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width: 0;">
    </div>
</div>
var delay = 0;
var percent = 0;

var iID = setInterval(function() {
    percent += 10;
    $('.text').text('Text ' + percent + '/100');
    $('.progress-bar').css('width', percent + '%').attr('aria-valuenow', percent);    
    if (percent === 100) {
        clearInterval(iID);
    }
}, delay);

作为解释,许多答案将指出这样一个事实:大多数浏览器在UI线程上运行JavaScript,因此在执行JavaScript时无法更新界面。相反,浏览器将显示

虽然记住这一点很重要,但它并不适用于您的代码。如果要更新进度条,请执行以下操作:

for (i = 0; i < len; i++) {
    updateProgressBar(i)
};
当调用之间的延迟为0毫秒时,浏览器没有时间更新UI,但没有时间完成600毫秒CSS转换。因此,直到最后才看到动画

如图所示,您可以通过使用CSS移除过渡效果来防止浏览器延迟宽度更新,如下所示:

for (i = 0; i < len; i++) {
    updateProgressBar(i)
};
.progress.进度条{
-webkit转换:无;
-o-转变:无;
过渡:无;
}
如果你在很多项目中循环,增量更新将提供某种形式的动画。如果您想保留通用用例的样式,可以在代码中关闭和打开转换。到,所以您只需要调用
.css(“transition”,“none”)

当然,取决于你为每部电影做了多少工作,JavaScript可能会在你能够直观地检测到所有UI更改之前完成,在这种情况下,延长延迟不会有什么坏处。如果要测试运行时间较长的进程,可以使用以下方法:

函数睡眠(睡眠时间){
var开始=+新日期;
while(+new Date-start
这里有一个演示,您可以在其中使用,每个设置都是一个变量,您可以对其进行配置以查看其反应,但最好的办法是有条件地删除转换

堆栈片段中的演示
var延迟、numMovies、throttledMovies、休眠时间、removeTransition;
$(“#delay”).change(function(){delay=this.value}).change()
$(“#movies”).change(function(){numMovies=this.value}).change()
$(“#sleep”).change(function(){sleepTime=this.value}).change()
$(“#转换”).change(function(){removeTransition=this.checked}).change()
$(“#加载电影”)。单击(加载电影);
函数loadMovies(){
var i=0;
throttledMovies=Movies.slice(0,numMovies)
如果(删除转换){
$(“#进度条电影”).css(“过渡”,“无”);
}
var interval=setInterval(函数(){
电影(一)
如果(++i>=numMovies){
间隔时间;
$(“#进度条电影”).css(“过渡”,“宽度.6s轻松”);
}
},延误);
};
功能加载电影(一){
var movie=throttledMovies[i];
变量完成百分比=((i+1)/numMovies)*100;
睡眠(睡眠时间);
//更新文本
$(“#procNum”).text(“+(i+1)+”/“+numvies+”);
$(“#procmoine”).text(movie.Title);
//更新进度条
$(“#进度条电影”)
.css('width',percentComplete+'%'))
.attr('aria-valuenow',完成百分比);
};
功能睡眠(睡眠时间){
var开始=+新日期;
while(+new Date-start

延迟(毫秒)
#电影
睡眠时间(毫秒)
删除转换?


加载电影

当前标题:
进展:


SO上提供的注释可能会有所帮助。但是这并不能解释为什么文本会改变,而不是css元素。你有没有尝试过取代
setInterval
?@SaiKrishnaDeep我的道歉我链接到了错误的小提琴,请看我的编辑。太好了!但是如何确保动画仍然存在?据我所知,如果我没有错的话,过渡时间应该比延迟时间短。你的小提琴对我有用,没有添加
transition:none也是。当我做出改变时,它也在我的网站上运行。我再核对一遍。同时@OhAuth你能回答我在上面的疑问吗comment@SaiKrishnaDeep我的解决方案