You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 08:40:56