我正在开发 Blazor 项目,我在移动浏览器上面临引导进度栏的问题。
我通过两个按钮和一个进度条来展示我的问题,一个按钮启动它,另一个按钮停止它。动画是使用过渡属性来管理的。它在我的台式机和笔记本电脑上按预期工作,但在移动浏览器上失败(但是它也可以在使用开发工具的模拟移动浏览器上工作)。
在移动浏览器上,我在第一次按下“停止”按钮后开始遇到问题。第二次按“开始”不会正确重置进度条,尽管有“转换:无”指令,进度条仍开始缓慢增加。之后连续按下停止和开始按钮就会被破坏(在 swisstransfer 文件共享服务上可以找到在移动设备上观察到的错误的屏幕记录:https://www.swisstransfer.com/d/ec018149-090a-46bf-b798 -8527055f0dc8)。
提前谢谢您
@page "/"
@* The progress bar ===================================================================*@
<div style="padding-bottom: 5px;">
<div class="progress" style="height: 10px;">
<div class="progress-bar" style="width: @_progressPercent%; background-color: @_progressColor; transition: @_transition"></div>
</div>
</div>
<button disabled="@_startButtonIsDisabled" @onclick="StartProgressBar">Start</button>
<button disabled="@_stopButtonIsDisabled" @onclick="StopProgressBar">Stop</button>
@code {
private Timer? _timer;
private int _counter;
private string _progressColor="grey";
private string _transition="none";
private int _progressPercent=100;
private double _t1 = 4;
private double _t2 = 8;
private double _tend = 16;
private DateTime _timerStartTime;
private bool _startButtonIsDisabled = false;
private bool _stopButtonIsDisabled = true;
private void TimerCallback(object? o)
{
_counter++;
switch (_counter)
{
case 0:
_progressPercent = (int)(100 * ( 1 - _t1 / _tend));
_transition = $"width {_t1}s linear";
InvokeAsync(StateHasChanged); // Update the UI
break;
case 1:
_progressPercent = (int)(100 * ( 1 - _t2 / _tend));
_progressColor = "orange";
_transition = $"width {_t2-_t1}s linear";
InvokeAsync(StateHasChanged); // Update the UI
_timer.Change(1000*(int)(_t2-_t1), Timeout.Infinite); // Set timer to _t2-_t1 seconds for the next event
break;
case 2:
_progressPercent = 0;
_progressColor = "red";
_transition = $"width {_tend-_t2}s linear";
InvokeAsync(StateHasChanged); // Update the UI
_timer.Change(1000*(int)(_tend-_t2), Timeout.Infinite); // Set timer to _tend-_t2 seconds for the next event
break;
case 3:
InvokeAsync(StateHasChanged); // Update the UI
_timer.Dispose(); // Stop the timer
break;
}
}
void StartProgressBar()
{
_startButtonIsDisabled = true;
_stopButtonIsDisabled = false;
_timerStartTime = DateTime.Now;
// reset the progress bar ==================
_counter = -1;
ResetProgressBar();
InvokeAsync(StateHasChanged);
_timer = new Timer(TimerCallback, null, 0, (int)_t1 * 1000);
}
void ResetProgressBar()
{
_progressPercent = 100;
_progressColor = "green";
_transition = "none";
}
void StopProgressBar()
{
_startButtonIsDisabled = false;
_stopButtonIsDisabled = true;
_timer.Dispose(); // Stop the timer
var ts = DateTime.Now - _timerStartTime;
_progressPercent = (int)(100 * ( 1 - ts.TotalMilliseconds / (_tend*1_000)));
_transition = "none";
}
}
ResetProgressBar();
InvokeAsync(StateHasChanged);
_timer = new Timer(TimerCallback, null, 0, (int)_t1 * 1000);
在移动设备上,由于某些原因,似乎新计时器的创建发生在 ResetProgressBar() 和 InvokeAsync(StateHasChanged) 执行完成之前。为了解决这个问题,我需要在计时器构造中添加 dueTime,如下所示: _timer = new Timer(TimerCallback, null, 5, (int)_t1 * 1000);在这种情况下延迟 5 毫秒。