Blazor项目Bootstrap进度条移动浏览器过渡行为异常求助
Blazor中Bootstrap进度条移动端启停后无法重置的问题解决
问题现象
开发的Blazor项目中,使用Bootstrap进度条结合CSS transition实现分段动画,在桌面端及浏览器模拟器中正常,但真实移动浏览器存在异常:首次点击停止后,再次启动时进度条无法正确重置为100%,即便设置了transition: none,仍会缓慢增长,后续反复启停均失效。
问题根源
移动端浏览器的CSS渲染引擎会对连续的样式变更进行优化合并,当重置进度条时,transition: none的设置和宽度变更可能被合并执行,导致浏览器未及时禁用过渡效果,仍沿用之前的过渡动画参数,从而出现进度条异常缓慢增长的情况。
解决方案
方案1:拆分样式更新步骤,强制浏览器重绘
通过异步等待让浏览器先完成无过渡样式的应用,再启动动画定时器。修改StartProgressBar方法为异步:
async void StartProgressBar() { _startButtonIsDisabled = true; _stopButtonIsDisabled = false; _timerStartTime = DateTime.Now; // 重置进度条状态 _counter = -1; ResetProgressBar(); StateHasChanged(); // 等待浏览器完成重绘,确保transition:none生效 await Task.Delay(1); _timer = new Timer(TimerCallback, null, 0, (int)_t1 * 1000); }
同时,在StopProgressBar方法中也添加重绘等待,确保停止时样式正确生效:
async void StopProgressBar() { _startButtonIsDisabled = false; _stopButtonIsDisabled = true; _timer.Dispose(); var ts = DateTime.Now - _timerStartTime; _progressPercent = (int)(100 * (1 - ts.TotalMilliseconds / (_tend*1_000))); _transition = "none"; StateHasChanged(); await Task.Delay(1); }
方案2:使用CSS类管理过渡状态(更稳定)
避免直接修改内联样式,通过切换CSS类来控制过渡效果,减少浏览器样式合并的影响:
- 添加CSS样式到项目中:
.progress-bar.no-transition { transition: none !important; } .progress-bar.transition-t1 { transition: width 4s linear; } .progress-bar.transition-t2 { transition: width 4s linear; } .progress-bar.transition-tend { transition: width 8s linear; }
- 修改进度条的Razor代码:
<div class="progress-bar @_transitionClass" style="width: @_progressPercent%; background-color: @_progressColor;"></div>
- 更新代码逻辑中的过渡控制:
@code { // 替换原_transition字段为_transitionClass private string _transitionClass = "no-transition"; private void TimerCallback(object? o) { _counter++; switch (_counter) { case 0: _progressPercent = (int)(100 * (1 - _t1 / _tend)); _transitionClass = "transition-t1"; InvokeAsync(StateHasChanged); break; case 1: _progressPercent = (int)(100 * (1 - _t2 / _tend)); _progressColor = "orange"; _transitionClass = "transition-t2"; InvokeAsync(StateHasChanged); _timer.Change(1000*(int)(_t2-_t1), Timeout.Infinite); break; case 2: _progressPercent = 0; _progressColor = "red"; _transitionClass = "transition-tend"; InvokeAsync(StateHasChanged); _timer.Change(1000*(int)(_tend-_t2), Timeout.Infinite); break; case 3: InvokeAsync(StateHasChanged); _timer.Dispose(); break; } } void ResetProgressBar() { _progressPercent = 100; _progressColor = "green"; _transitionClass = "no-transition"; } void StopProgressBar() { _startButtonIsDisabled = false; _stopButtonIsDisabled = true; _timer.Dispose(); var ts = DateTime.Now - _timerStartTime; _progressPercent = (int)(100 * (1 - ts.TotalMilliseconds / (_tend*1_000))); _transitionClass = "no-transition"; } }
原理说明
通过拆分异步更新或使用CSS类切换,让浏览器有足够时间处理样式变更,确保transition: none在进度条宽度重置前生效,避免移动端浏览器的样式合并优化导致的动画残留问题。
内容的提问来源于stack exchange,提问作者akasolace
相关产品推荐
相关产品推荐

