下面我将从前端实现后端集成两个方面,为您提供几种常用且效果出色的代码示例和实现思路。


核心思想

无论使用哪种效果,其基本原理都是一样的:

  1. 触发加载状态:当用户执行一个操作(如点击按钮、提交表单、发起AJAX请求)时,通过 JavaScript 显示一个加载动画。
  2. 隐藏加载状态:当后端处理完成,返回响应后,通过 JavaScript 隐藏加载动画。

简单的全屏遮罩加载动画 (推荐)

这是最常用、最直观的方式,通常是一个半透明的遮罩层覆盖在整个页面上,中间有一个旋转的图标。

创建加载遮罩组件 (Partial View)

Views/Shared 文件夹下创建一个名为 _LoadingPartial.cshtml 的文件。

<!-- Views/Shared/_LoadingPartial.cshtml -->
@*
    这个部分视图将作为加载遮罩。
    默认是隐藏的,通过 JavaScript 类来控制其显示和隐藏。
*@
<div id="loadingOverlay" class="loading-overlay">
    <div class="spinner"></div>
    <p>正在加载,请稍候...</p>
</div>

添加 CSS 样式

wwwroot/css/site.css (或你自定义的CSS文件) 中添加以下样式:

/* wwwroot/css/site.css */
/* 加载遮罩层样式 */
.loading-overlay {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background-color: rgba(0, 0, 0, 0.5); /* 半透明黑色背景 */
    display: flex; /* 使用 flexbox 居中内容 */
    justify-content: center;
    align-items: center;
    z-index: 9999; /* 确保它在最上层 */
    color: white;
    font-size: 1.2em;
}
/* 默认隐藏加载遮罩 */
.loading-overlay.hidden {
    display: none;
}
/* 旋转的加载动画 (spinner) */
.spinner {
    border: 5px solid #f3f3f3; /* Light grey */
    border-top: 5px solid #3498db; /* Blue */
    border-radius: 50%;
    width: 50px;
    height: 50px;
    animation: spin 1s linear infinite;
    margin-bottom: 20px;
}
@keyframes spin {
    0% { transform: rotate(0deg); }
    100% { transform: rotate(360deg); }
}

在布局文件中引入遮罩和 JavaScript

Views/Shared/_Layout.cshtml 文件中,将 _LoadingPartial.cshtml 和控制它的 JavaScript 代码放进去。

<!-- Views/Shared/_Layout.cshtml -->
...
<body>
    @* 在 body 的开头或结尾引入加载遮罩 *@
    @await Html.PartialAsync("_LoadingPartial")
    <header>...</header>
    <div class="container">...</div>
    <footer>...</footer>
    @* 在页面底部引入你的 JS 文件,或者直接在这里写脚本 *@
    <script>
        // 显示加载遮罩的函数
        function showLoading() {
            document.getElementById('loadingOverlay').classList.remove('hidden');
        }
        // 隐藏加载遮罩的函数
        function hideLoading() {
            document.getElementById('loadingOverlay').classList.add('hidden');
        }
        // === 1. 页面首次加载时显示加载效果 ===
        // 当整个页面文档加载完成后执行
        document.addEventListener('DOMContentLoaded', function () {
            // 页面加载完成后,我们希望在很短的延迟后立即显示遮罩,
            // 然后它会在主要资源(如图片)加载完成后自动隐藏。
            // 但更常见的做法是只在AJAX请求时显示。
            // 如果非要页面加载时显示,可以这样:
            showLoading();
        });
        // 当整个页面(包括图片、脚本等所有资源)完全加载后,隐藏遮罩
        window.addEventListener('load', function () {
            hideLoading();
        });
        // === 2. 为所有 AJAX 请求自动添加加载效果 (推荐) ===
        // 使用 jQuery 的 ajaxSetup 来全局配置
        // 如果你使用的是原生 JavaScript,可以使用 fetch API 的拦截器
        $(document).ajaxStart(function () {
            showLoading();
        }).ajaxStop(function () {
            hideLoading();
        });
        // 如果你使用原生 Fetch API
        // const originalFetch = window.fetch;
        // window.fetch = async function (...args) {
        //     showLoading();
        //     try {
        //         const response = await originalFetch.apply(this, args);
        //         return response;
        //     } finally {
        //         hideLoading();
        //     }
        // };
    </script>
</body>

在表单提交或 AJAX 请求中使用

当你提交一个表单或发起 AJAX 请求时,ajaxStartajaxStop 事件会自动触发,加载遮罩会自动显示和隐藏。

示例:表单提交

<form asp-action="Create" asp-controller="Home" method="post" id="myForm">
    <input type="text" name="name" placeholder="输入名称" />
    <button type="submit">提交</button>
</form>

当你点击提交按钮时,表单会提交,同时加载遮罩会显示,直到服务器返回响应并页面刷新(或部分刷新)。

示例:使用 jQuery 发起 AJAX 请求

$.ajax({
    url: '/api/data',
    type: 'GET',
    success: function (data) {
        console.log('数据加载成功:', data);
        // 在这里处理返回的数据
    },
    error: function (error) {
        console.error('数据加载失败:', error);
    }
    // 不需要在这里手动调用 showLoading/hideLoading,
    // 因为全局的 ajaxStart/Stop 已经处理了
});

使用现成的 UI 框架 (如 Bootstrap)

如果你已经在使用 Bootstrap,可以利用它的组件和 JavaScript 来实现更美观的效果。

修改 _LoadingPartial.cshtml

<!-- Views/Shared/_LoadingPartial.cshtml -->
@*
    使用 Bootstrap 的 Modal 组件作为加载遮罩
*@
<div class="modal fade" id="loadingModal" tabindex="-1" role="dialog" aria-hidden="true" data-backdrop="static" data-keyboard="false">
    <div class="modal-dialog modal-sm modal-dialog-centered" role="document">
        <div class="modal-content">
            <div class="modal-body text-center">
                <div class="spinner-border text-primary" role="status">
                    <span class="sr-only">Loading...</span>
                </div>
                <p class="mt-2">正在加载,请稍候...</p>
            </div>
        </div>
    </div>
</div>

修改 _Layout.cshtml 中的 JavaScript

<!-- Views/Shared/_Layout.cshtml -->
...
<script src="~/lib/jquery/dist/jquery.min.js"></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
<script>
    // 显示加载模态框
    function showLoading() {
        $('#loadingModal').modal('show');
    }
    // 隐藏加载模态框
    function hideLoading() {
        $('#loadingModal').modal('hide');
    }
    // === 为 AJAX 请求自动添加加载效果 ===
    $(document).ajaxStart(function () {
        showLoading();
    }).ajaxStop(function () {
        hideLoading();
    });
    // === 页面首次加载时显示加载效果 ===
    document.addEventListener('DOMContentLoaded', function () {
        showLoading();
    });
    window.addEventListener('load', function () {
        hideLoading();
    });
</script>

这种方式的好处是与 Bootstrap 的视觉风格完全统一,且模态框可以阻止用户在加载时与页面交互(data-backdrop="static")。


页面内局部加载效果

有时你不需要全屏遮罩,只需要在某个按钮或表格旁边显示一个加载图标。

HTML 结构

<button id="loadDataBtn" class="btn btn-primary">
    <span class="spinner-border spinner-border-sm d-none" id="btnSpinner" role="status" aria-hidden="true"></span>
    加载数据
</button>
<div id="dataContainer">
    <!-- 数据将在这里显示 -->
</div>

JavaScript 代码

<script>
    document.getElementById('loadDataBtn').addEventListener('click', function() {
        const btn = this;
        const spinner = document.getElementById('btnSpinner');
        const container = document.getElementById('dataContainer');
        // 1. 禁用按钮,显示加载图标
        btn.disabled = true;
        spinner.classList.remove('d-none');
        // 2. 模拟 AJAX 请求
        fetch('/api/data')
            .then(response => response.json())
            .then(data => {
                // 3. 请求成功,处理数据
                container.innerHTML = '<p>数据加载成功: ' + JSON.stringify(data) + '</p>';
            })
            .catch(error => {
                // 4. 请求失败,显示错误信息
                container.innerHTML = '<p class="text-danger">加载数据失败。</p>';
                console.error('Error:', error);
            })
            .finally(() => {
                // 5. 无论成功失败,都恢复按钮状态
                btn.disabled = false;
                spinner.classList.add('d-none');
            });
    });
</script>

总结与选择建议

方案 优点 缺点 适用场景
全屏遮罩 用户体验好,明确告知用户系统正在处理;实现简单,可全局复用。 会阻止用户与整个页面的交互。 表单提交、页面跳转、数据量大的AJAX请求,这是最通用和推荐的首选方案。
Bootstrap Modal 视觉风格统一,美观;可配置性强(如阻止交互)。 依赖 Bootstrap 框架。 已经在使用 Bootstrap 的项目中,希望获得更精致效果的场景。
局部加载 交互友好,不影响页面其他部分;轻量。 只能指示局部操作的状态。 按钮点击后更新局部数据、分页加载等不希望中断用户当前操作的场景。

对于大多数 .NET Web 应用,方案一(全屏遮罩) 结合 全局 AJAX 拦截 是最实用、最有效的解决方案,你可以根据具体需求,灵活组合或修改这些方案。