Blazor中<img>加载新资源时显示旧图,如何切换为加载状态?
解决Blazor图片切换时旧图残留的问题
针对你遇到的Blazor中<img>切换URL时旧图持续显示到新图加载完成的问题,这里提供两种实用的解决思路,都能让你在加载期间显示loading.gif或者清空旧图:
方案一:通过状态控制显示加载状态
核心思路是监测ImageInfo参数变化,立即触发加载状态,清空当前图片的显示,等新图加载完成后再恢复显示,同时让父容器的loading背景生效。
修改你的ImageViewer组件:
<div class="loading @(isImageLoading ? "" : "loaded")"> <img class="attachment" src="@(isImageLoading ? "data:image/gif;base64,R0lGODlhAQABAIAAAMLCwgAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==" : url)" type="image/jpeg" @onload="() => isImageLoading = false" @onerror="() => isImageLoading = false" /> </div> @code { [Parameter] public ImageInfo ImageInfo { get; set; } = default!; private string url => ImageInfo.GetImageUrl; private bool isImageLoading = true; protected override void OnParametersSet() { // 每次ImageInfo变更时,重置加载状态 if (ImageInfo != null) { isImageLoading = true; } base.OnParametersSet(); } }
更新CSS样式,确保加载状态下背景loading可见,加载完成后隐藏:
.loading { background: transparent url(./loading.gif) no-repeat scroll center center; min-height: 200px; /* 根据你的布局设置合适高度,保证loading图能显示 */ } .loading.loaded { background: none; } .attachment { width: 100%; height: auto; display: block; }
方案二:预加载图片后再替换显示
这种方式会先在后台加载新图片,等加载完成后再替换<img>的src,实现无缝切换,期间同样可以显示loading状态。
修改ImageViewer组件:
<div class="loading @(isImageLoading ? "" : "loaded")"> <img class="attachment" src="@displayUrl" type="image/jpeg" /> </div> @code { [Parameter] public ImageInfo ImageInfo { get; set; } = default!; private string url => ImageInfo.GetImageUrl; private string displayUrl = "data:image/gif;base64,R0lGODlhAQABAIAAAMLCwgAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw=="; private bool isImageLoading = true; protected override async Task OnParametersSetAsync() { if (ImageInfo == null) return; var newImageUrl = url; // 避免重复加载同一图片 if (newImageUrl == displayUrl) return; isImageLoading = true; // 预加载新图片 await PreloadImage(newImageUrl); displayUrl = newImageUrl; isImageLoading = false; StateHasChanged(); } private async Task PreloadImage(string imageUrl) { var image = new Image(); var loadCompletion = new TaskCompletionSource<bool>(); image.OnLoad += (_, __) => loadCompletion.SetResult(true); image.OnError += (_, __) => loadCompletion.SetResult(true); // 加载失败也继续执行 image.Src = imageUrl; await loadCompletion.Task; } }
两种方案的选择
- 方案一更简单易维护,适合大多数场景,直接利用原生图片的加载事件控制状态,清空旧图后父容器的loading背景会自动显示。
- 方案二的切换体验更流畅,不会出现图片闪烁,但需要额外处理预加载逻辑,适合对体验要求较高的场景。
额外提示:如果图片存在缓存导致加载不刷新的问题,可以在URL后添加随机参数(比如$"{url}?t={DateTime.Now.Ticks}"),确保每次请求新资源,但注意结合你的缓存策略调整。
内容的提问来源于stack exchange,提问作者James Harcourt
相关产品推荐
相关产品推荐

