最近在用zombie js做unit test的时候,发现跑个测试非常慢, 每个测试至少5000ms,多的达到20000ms。因为是把所有的第三方库打包到一个js文件里,所以只能一个一个删掉导入的第三库,最后发现,原来是jquery.mask.js引起的!
jquery.mask.js还是很好用的,最要用于输入的验证,包括ip地址,日期等等。配置灵活,可以根据自己的需要设置不同的运行方式。而且还支持动态的监视页面,即如果通过js来添加新字段,也能对这个字段进行validation,而不需要重新载入页面。但是,就是为了支持这个动态监视,它调用了一个setInterval方法来验证新的字段,这就导致了它其实隔断时间就要运行下代码,然后在unit test的时候,把测试时间延长到了这么久。
为了修复这个问题,阅读了整个jquery.mask.js的源码,这里稍微分享下自己的心得。
/**
* jquery.mask.js
* @version: v1.11.4
* @author: Igor Escobar
*
* Created by Igor Escobar on 2012-03-10. Please report any bug at http://blog.igorescobar.com
*
* Copyright (c) 2012 Igor Escobar http://blog.igorescobar.com
*
* The MIT License (http://www.opensource.org/licenses/mit-license.php)
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
/* jshint laxbreak: true */
/* global define, jQuery, Zepto */
'use strict';
// UMD (Universal Module Definition) patterns for JavaScript modules that work everywhere.
// https://github.com/umdjs/umd/blob/master/jqueryPluginCommonjs.js
(function (factory) {
//这块主要是为了UMD,模块化JS
if (typeof define === 'function' && define.amd) {
define(['jquery'], factory);
} else if (typeof exports === 'object') {
module.exports = factory(require('jquery'));
} else {
factory(jQuery || Zepto);
}
}(function ($) {
<span style="white-space:pre"> </span>//Mask可以认为是plugin的本身,是root,定义了主要的实现逻辑,函数等等,可以理解为java里的一个class
var Mask = function (el, mask, options) {
el = $(el);
var jMask = this, oldValue = el.val(), regexMask;
mask = typeof mask === 'function' ? mask(el.val(), undefined, el, options) : mask;
<span style="white-space:pre"> </span>//这里的p感觉很像一个内部类,它里面的一些方法就是整个验证逻辑的具体实现
var p = {
invalid: [],
getCaret: function () {
try {
var sel,
pos = 0,
ctrl = el.get(0),
dSel = document.selection,
cSelStart = ctrl.selectionStart;
// IE Support
if (dSel && navigator.appVersion.indexOf('MSIE 10') === -1) {
sel = dSel.createRange();
sel.moveStart('character', el.is('input') ? -el.val().length : -el.text().length);
pos = sel.text.length;
}
// Firefox support
else if (cSelStart || cSelStart === '0') {
pos = cSelStart;
}
return pos;
} catch (e) {}
},
setCaret: function(pos) {
try {
if (el.is(':focus')) {
var range, ctrl = el.get(0);
if (ctrl.setSelectionRange) {
ctrl.setSelectionRange(pos,pos);