当页面发起Ajax请求时,用户往往并不知道后台正在处理数据,如果此时继续点击按钮、切换选项或提交表单,就可能出现重复下单、数据覆盖等严重问题。jQuery BlockUI插件正是为解决这类场景而生,它可以在请求期间用一个半透明遮罩层覆盖页面或指定区域,阻止用户的一切鼠标和键盘操作,请求完成后再解除锁定,整个过程体验流畅且高度可定制。

一、BlockUI插件的基本原理与引入方式
BlockUI的核心思路其实并不复杂:它在页面中动态插入一个覆盖层元素,通过CSS将其定位为fixed或absolute,铺满整个视口或目标容器,并设置较高的z-index压在其他内容之上。这样一来,鼠标点击、滚轮滚动等事件都被这个覆盖层拦截,下层的表单和按钮自然无法被操作。同时它还会插入一个提示消息层,用来展示Loading文字或动画。
使用之前需要先引入jQuery库和blockUI插件文件,可以直接使用官方CDN地址,也可以下载到本地项目目录:
<!-- 先引入jQuery --> <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script> <!-- 再引入blockUI插件 --> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.blockUI/2.70/jquery.blockUI.min.js"></script>
引入后可以通过$.blockUI调用全局锁定,也可以通过$('#id').block()锁定某个具体元素。插件加载成功后,$.blockUI会作为一个可调用的函数挂载在jQuery对象上,如果控制台提示该函数未定义,通常是插件脚本没有正确加载,需要检查引入顺序和路径。
二、在Ajax请求期间锁定与解锁页面的完整示例
最典型的用法是配合$.ajax的全局事件。可以在ajaxStart时锁定页面,在ajaxStop时解除锁定,这样页面中所有Ajax请求都会自动受到保护,不需要在每个请求里重复写锁定代码:
$(document).ajaxStart(function () {
$.blockUI({ message: '<h3>数据加载中,请稍候...</h3>' });
});
$(document).ajaxStop(function () {
$.unblockUI();
});如果只想针对某个具体请求进行锁定,则应该在请求的beforeSend回调中调用锁定,在complete回调中解锁。这种写法的好处是可以对不同请求展示不同的提示文案:
$('#submitBtn').on('click', function () {
$.ajax({
url: '/api/order/create',
type: 'POST',
data: $('#orderForm').serialize(),
beforeSend: function () {
// 阻止按钮重复点击,双重保险
$('#submitBtn').prop('disabled', true);
$.blockUI({ message: '<h3>正在提交订单...</h3>' });
},
success: function (res) {
alert('提交成功');
},
error: function () {
alert('请求失败,请重试');
},
complete: function () {
$('#submitBtn').prop('disabled', false);
$.unblockUI();
}
});
});需要注意一点:complete回调无论成功还是失败都会执行,因此解锁代码必须写在这里,而不是写在success里,否则一旦请求出错,页面就会被永久锁死,用户只能刷新页面才能恢复。另外建议同时禁用触发按钮,因为遮罩层虽然拦截了鼠标操作,但在某些极端情况下双保险更稳妥。
三、自定义Loading样式:文字、颜色、动画与图片
BlockUI默认的样式比较朴素,一块白底灰边的矩形加上提示文字。实际项目中通常需要与整体UI风格保持一致,插件提供了丰富的配置项供定制。下面是一个较为完整的自定义示例:
$.blockUI({
// 提示内容,可以包含任意HTML
message: '<div class="loading-box"><img src="/images/spinner.gif" alt="加载中"/><p>玩命加载中,请稍候...</p></div>',
// 遮罩层样式
css: {
border: 'none',
padding: '20px',
backgroundColor: 'transparent',
opacity: 0.9,
color: '#fff'
},
// 遮罩背景色
overlayCSS: {
backgroundColor: '#000',
opacity: 0.6
}
});其中message支持任意HTML字符串,这是实现复杂样式的基础。配合自定义CSS类,可以做出带圆角卡片、阴影、旋转动画的现代加载效果,例如使用CSS3动画替代GIF图片:
.loading-box {
text-align: center;
color: #fff;
}
.loading-box .spinner {
width: 40px;
height: 40px;
margin: 0 auto 12px;
border: 4px solid rgba(255, 255, 255, 0.3);
border-top-color: #fff;
border-radius: 50%;
animation: spin 0.8s linear infinite;
}
@keyframes spin {
to { transform: rotate(360deg); }
}
<div class="loading-box">
<div class="spinner"></div>
<p>正在处理,请稍候...</p>
</div>如果觉得逐项配置麻烦,还可以使用$.blockUI.defaults一次性覆盖全部默认值,后续调用就无需重复传参。此外,配置项中的fadeIn、fadeOut和timeout也很有用:设置timeout可以让遮罩在指定毫秒后自动解除,作为请求异常时的兜底保护,避免页面被无限锁住。
四、局部锁定与常见问题的规避技巧
除了锁定整个页面,BlockUI还支持只锁定页面中的某个区域,例如一个数据表格容器。局部锁定时遮罩只会覆盖该元素,页面其他部分仍然可以正常操作,适合列表刷新、局部更新等场景:
$('#dataTable').block({
message: '<p style="color:#333;">表格数据加载中...</p>',
overlayCSS: { backgroundColor: '#f5f5f5', opacity: 0.7 }
});
// 数据加载完成后解除局部锁定
$('#dataTable').unblock();实际使用中还有几个容易踩的坑值得注意。第一,如果锁定后遮罩的位置不随页面滚动而变化,多半是因为插件版本较旧或DOCTYPE缺失,确保页面声明了标准的HTML5文档类型。第二,默认配置下用户仍可通过Tab键聚焦到遮罩下的元素,对无障碍要求高的项目可以给覆盖层设置cursor为wait并在锁定时把焦点移出表单区域。第三,多次连续调用block可能产生叠加的遮罩层,务必保证每次锁定都有对应的unblock调用,用完即解,保持锁定状态的对称性。
总的来说,BlockUI以极低的接入成本解决了Ajax期间的用户操作隔离问题,再配合灵活的样式定制,既能保证数据安全,又能提供良好的加载体验,是老牌jQuery项目中非常值得使用的实用插件。
jQuery BlockUIAjax请求Loading样式修改时间:2026-09-02 04:08:31