本文介绍了为什么进度栏不像文本动态改变?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 我在 setTimeout()函数后动态更新一些元素。 jQuery函数 .text()似乎是在处理数组的每个索引变化时动态更新。但是通过 .css()和 .attr()更改的引导进度条似乎不会动态更新。这是我的页面: http://imdbnator.com/process.php?id= f144caf0843490c0d3674113b03da0c5& redirect = false 您可以看到文本已更改,但进度条仅在整个 setTimeout 函数完成。此外,如果我设置 delay = 1000 。有用。但它的应用程序减慢。因此,我需要 delay = 0 。 var inc = 0; var maxc = a.length; var delay = 0; // delay milliseconds var iID = setInterval(function(){ var index = inc; var movie = a [inc]; //开始处理函数 //处理时的样式 var markerPer =((index + 1)/ rawListNum)* 100; //标记百分比 $(#procNum)。 1)+/+ rawListNum +)); //处理数字 $(#procMovie)text(movie); //处理名称 $ 'progressbar'])。css(width,markerPer +%)。attr(aria-valuenow,markerPer); //进度条 - >不工作 if > = maxc)clearInterval(iID); }, delay); } 解决方案很多答案都指出,大多数浏览器在UI线程上运行JavaScript ,因此它们不能在执行JavaScript时更新界面。相反,浏览器将等待Javascript完成并将控制权返回到UI线程。 虽然这一点很重要,但它不会对你的代码起作用。如果你正在更新进度条,这样做: for(i = 0; i< len; i ++){ updateProgressBar(i)}; 然后它肯定会阻止UI更新到结束。 但您已经在使用 setTimeout 或 setInterval ,它们具有到代码的异步回调。这意味着JavaScript能够暂停足够长的时间来管理任何UI消息。 正如你的问题,为什么,如果UI正在更新,是进度条不更新为? 答案在于 Bootstrap将以下CSS 应用于进度栏: .progress-bar { -webkit-transition:width .6s ease; -o-transition:width .6s ease; transition:width .6s ease; } 当调用之间的延迟为0ms时,浏览器 strong>有时间更新UI,但不有时间完成600毫秒的CSS转换。因此,直到结束,才会看到动画。 由于 OhAuth指出,您可以通过删除CSS的过渡效果来阻止浏览器延迟宽度更新,如下所示: .progress .progress-bar { -webkit-transition:none; -o-transition:none; transition:none; } 如果循环遍历很多项目,某种动画。如果你想保留通用用例的样式,可以在代码中关闭和打开转换。从 jQuery 1.8开始,您可以更新CSS属性而不使用供应商前缀,因此您只需要 .css(transition,none)。 当然,为每个电影做,JavaScript可能能够完成之前,你可以视觉检测所有的UI更改,在这种情况下延长延迟不会伤害。如果您想测试运行时间较长的进程,可以使用以下睡眠功能 a>: function sleep(sleepyTime){ var start = + new Date ; while(+ new Date - start< sleepyTime){} } 这里是一个演示,你可以玩,其中每个设置是一个变量,你可以配置看看它会如何反应,但最好的赌注只是有条件地删除转换。 在Stack Snippets中演示 {delay = this.value})。change()$(#movies)。change(function(){numMovies = this.value})。 {sleepTime = this.value})。change()$(#transition)。change(function(){removeTransition = this.checked})change()$(#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 .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){}} < link href =// cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.2/css/bootstrap.css =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>延迟(ms)< / label>< input type =numbervalue =0min = 0 max = 1000 id =delay/> ;< label for =movies>#Movies< / label>< input type =numbervalue =250min = 0 max = 250 id =movies/>< label for = sleep>睡眠时间(ms)< / label>< input type =numbervalue =0min = 0 max = 1000 id =sleep/& >删除转换? < / label>< input type =checkboxchecked =trueid =transition/>< br />< br />< button class =btn btn-primary btn- lgid =loadMovies>加载电影< / button>< br />< br />< p> < b>当前标题< / b> ;:< span id =procMovie>< / span>< br / < b>进阶< / b> ;:< span id =procNum>< / span>< / p>< div class =progress> < div class =progress-barrole =progressbarid =progress-bar-moviearia-valuenow =0aria-valuemin =0aria-valuemax =100>< div>< / div> I'm dynamically updating a few elements after a setTimeout() function. The jQuery function .text() seems to dynamically update with each change of index of an array while processing. But a bootstrap progressbar which is being changed through .css() and .attr() doesnt seem to dynamically update. Here is my page : http://imdbnator.com/process.php?id=f144caf0843490c0d3674113b03da0c5&redirect=falseYou can see that the text gets changed but the progress bar only finishes after the whole setTimeout() function finishes. Also, if I set the delay = 1000. It works. But it slows down by application. Therefore, I need delay = 0. But why doesnt the progressbar change?Here is my snippetfunction 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);} 解决方案 By way of explanation, a lot of answers are going to point out the fact that most browsers run JavaScript on the UI thread, so they cannot update the interface when JavaScript is being executed. Instead, the browser will wait for the Javascript to finish and return control to the UI thread.While this is important to keep in mind, it doesn't come into play for your code. If you were updating the progress bar doing something like this:for (i = 0; i < len; i++) { updateProgressBar(i)};Then it would definitely prevent the UI from updating until the end. But you're already doing the right thing by using setTimeout or setInterval, which have asynchronous callbacks into the code. Meaning that the JavaScript is able to pause for long enough to pipe out any UI messages. As evidenced by the fact that the text is able to update dynamically.As your question asks, why, if the UI is getting updated, is the progress bar not updated as well?The answer lies in the fact that Bootstrap applies the following CSS to the progress bar:.progress-bar { -webkit-transition: width .6s ease; -o-transition: width .6s ease; transition: width .6s ease;}When the delay between calls is 0ms, the browser does have time to update the UI, but does not have time to complete the 600ms CSS transition. Consequently, you don't see the animation until the end.As OhAuth points out, you can prevent the browser from delaying the width update by removing the transition effect with CSS like this:.progress .progress-bar { -webkit-transition: none; -o-transition: none; transition: none;}If you're looping through a lot of items, the incremental updates will provide some sort of animation. If you wanted to leave on the styling for a generic use case, you could toggle the transitions off and on in your code. As of jQuery 1.8 you can update CSS properties without the vendor prefix, so you'd just need to call .css("transition","none").Of course, depending on how much work you're doing for each movie, the JavaScript may be able to finish before you can visually detect all of the UI changes, in which case extending the delay wouldn't hurt. If you'd like to test out longer running processes, you can use the following sleep function:function sleep(sleepyTime) { var start = +new Date; while (+new Date - start < sleepyTime){}}Here's a demo you can play around where each setting is a variable that you can configure to see how it would react, but the best bet is just to conditionally remove transitions.Demo in Stack Snippetsvar 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){}}<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> 这篇关于为什么进度栏不像文本动态改变?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!
10-29 03:02