页面阻塞(或称加载提示、遮罩层)是多数Web应用都会涉及到的一项功能,用于提示用户当前应用正在加载或处理数据,防止用户在交互中对未完成的操作产生误解或二次提交。然而,如何实现优质的页面阻塞效果一直是个备受关注的问题。本文将介绍一款名为BlockUI的jQuery插件在页面阻塞方面的应用,分析其原理,以及几种优化方法。
阻塞原理
最简单的页面阻塞方式是给遮罩层使用全屏幕的半透明背景,然后在中心位置放置一个图片加载提示符号。具体而言,一个最基本的阻塞效果需要使用以下CSS进行定义:
@keyframes spin { to { transform: rotate(360deg); } } .loading { position: absolute; top: 50%; left: 50%; width: 60px; height: 60px; margin-left: -30px; margin-top: -30px; border-radius: 50%; z-index: 9999; animation: spin 1s linear infinite; border: 3px solid rgba(0, 0, 0, 0.2); border-top-color: #337ab7; } /* 全局遮罩层 */ .mask { position: fixed; top: 0; left: 0; right: 0; bottom: 0; background-color: rgba(0, 0, 0, 0.4); z-index: 9998; }
这是一个使用了CSS3 animation的无限旋转的图标和全屏幕的黑色遮罩层的一个简单实现。但实际上,阻塞页面不单单是让用户看到一个图标,还需要控制有哪些事件可以被触发,哪些不可以。
在这个例子中,我们使用了jQuery的on方法对整个页面添加了一个针对keyup的事件进行拦截,即用户在遮罩层下按下了键盘,事件将被忽略。同时,我们将全局遮罩层上添加了一个类名用以标记它处理了阻塞页面功能:
$('body').on('keyup', function(e) { e.stopPropagation(); }); $.blockUI.defaults.baseZ = 9999; $.blockUI.defaults.message = ''; $.blockUI.defaults.overlayCSS = { backgroundColor: '#000', opacity: 0.4, cursor: 'wait' }; $('.mask').addClass('block_page').block({ onBlock: function() { $('html,body').animate({scrollTop:0}, 0); } });
BlockUI
BlockUI是一个jQuery插件,也是我们今天要介绍的主角,它是由Malsup在11年份创建出来的。其内部实现使用的是简单而又高效的计数阻塞法,而非常见的那种appendTo和clone这样的方法。
在开发中,我们通常会使用blockUI来实现ajax加载、遮罩层、边界防御、洞穴式操作、页面加载提示符等阻塞操作。
BlockUI使用了下面几个方法:
- $.blockUI(options): 打开阻塞层
- $.unblockUI(options): 关闭阻塞层
- $().block(options): 给指定元素打开阻塞层
- $().unblock(options): 给指定元素关闭阻塞层
其中options是一个包含多个属性的对象(这种写法是使用插件的常规风格,我们后续将使用它来进行演示)。常用的可选项包括:
- message: 弹出框的文本信息
- css: 弹出框的样式
- onBlock: 弹出框初始化执行的回调函数
- timeout: 自动隐藏的时间
- overlayCSS: 遮罩层的样式
性能优化
虽然blockUI默认使用了首选的计数阻塞法,但还是有一些优化方式可以让它耗费更少的资源,阻塞速度也更快。以下是其中几种优化方式:
尽可能少增加DOM节点数量
虽然我们可以在UI上增加相应的DOM节点来实现阻塞效果,但请尽量注意避免增加不必要的DOM节点。BlockUI就是一种很好的例子,使用BlockUI的计数阻塞法,使它不必在DOM中增加任何内容,而是仅仅使用计数器来记录需要阻塞的请求的数量,以此来显示和隐藏阻塞效果,从而提高了性能。
避免对DOM进行重排
DOM重排是一项十分费时的性能操作。在BlockUI的实现中,每一个需要阻塞请求的占用时间可能非常短。如果你频繁进行页面重排,它就会明显影响页面的响应速度。一个简单的解决办法是,如果你知道你的进度监控是更大的一块代码,那就把它们都封装在一起,使用一个重排,来替代每个请求单独使用一次。
套用已有的样式
为了让阻塞效果更美观,很多人都想自己设计一个样式或者直接使用别人的样式。但实际上,使用已有的样式会改善效率,并减少重复的工作。可以考虑使用Bootstrap等流行的UI库,使我们不必自己写样式。
通过图片预加载来缩短页面加载时间
在页面渲染完成之前,由于浏览器需要下载页面资源(包括脚本、样式、图片等)这个过程可能需要一段时间。可以通过预先加载大量图片来加速这个过程,并提高页面呈现速度。jQuery的图片预加载插件jquery.preload就是一个很好的选择。
JavaScript代码优化
在使用BlockUI时,推荐使用jQuery 1.10.x或更新版本,因为在这个版本中,jQuery将移除非常冗余的代码(该功能本身并不常用,但对于blockUI插件而言非常重要)。
小结
本文介绍了BlockUI这款应用广泛的页面阻塞效果插件,并通过分析其原理,与几种性能优化方式,来帮助前端开发者更好地掌握如何使用它。我们希望这篇文章可以帮到你学习BlockUI,同时通过优化你的代码,让你的网站响应更快并展现更优美的效果。