jQuery.Validate.js验证大表单的优化
最近在项目中有遇到一个Form表单中有200多个标签。在提交表单时网页会出现等待时间很长,甚至会出现网页奔溃的情况。
主要的原因是因为在使用jQuery.Validate.js进行Form验证的时候会花销大量时间。这些时间主要用在两个地方:
1.表单中标签的检查对应jQuery.Validate.js中checkForm()方法。
2.检查完标签后需要显示错误或成功信息对应jQuery.Validate.js中ShowErrors()方法。
先前我们是用的jQuery.Validate.js-1.8.0版本,我更新到最新的jQuery.Validate.js-1.15.1版本,发现验证时间没有得到明显的优化。
反而会与之前的版本会有冲突,冲突的地方在无法验证隐藏的控件,例如用了第三方的HTML编辑框插件,后面会隐藏一个textarea控件,之前低版本的会检测到这个,但是新版本的会忽略。问题在于新版本的js默认会跳过页面中不可见的元素。
1.8.0版本的ignore:[] 这里改为“.hidden”在checkForm()时会默认过滤掉页面中所有的不可见元素。
这是1.15.1种checkForm的方法:
checkForm: function() {
this.prepareForm();
for ( var i = 0, elements = ( this.currentElements = this.elements() ); elements[ i ]; i++ ) {
this.check( elements[ i ] );
}
return this.valid();
},
elements: function() {
var validator = this,
rulesCache = {}; // Select all valid inputs inside the form (no submit or reset buttons)
return $( this.currentForm )
.find( "input, select, textarea, [contenteditable]" )
.not( ":submit, :reset, :image, :disabled" )
.not( this.settings.ignore )//在这个地方会对隐藏元素进行过滤,返回的elements会少了很多隐藏的元素。
.filter( function() {
var name = this.name || $( this ).attr( "name" ); // For contenteditable
if ( !name && validator.settings.debug && window.console ) {
console.error( "%o has no name assigned", this );
} // Set form expando on contenteditable
if ( this.hasAttribute( "contenteditable" ) ) {
this.form = $( this ).closest( "form" )[ 0 ];
} // Select only the first element for each name, and only those with rules specified
if ( name in rulesCache || !validator.objectLength( $( this ).rules() ) ) {
return false;
} rulesCache[ name ] = true;
return true;
} );
},
这种处理的确可以减少很多不必要元素的check。但是经过测试这里的时间提升并不是十分明显。
但是这样处理后反而使得项目出现了不兼容的问题,因为像HTML编辑框等需要验证的背后隐藏元素也会被隐藏。
出于项目的需要,这里我将这个参数defaults中的ignore参数改为了input[type="hidden"]这样解决了兼容的问题。因为这个只对<input>标签中设置了"type=hidden"的元素忽略检查。
说了这么多并没有提到如何提升验证性能的方面。下面讨论下,由于本人也是小菜,希望大神勿喷。
上面有提到验证所花销的时间主要花在两个函数上,那么我们就从这两个函数说起:
1.checkForm().
从上面其实我们已经看出来了,将ignore设置值从而过滤掉一些隐藏的元素本身就是一种对checkForm()函数执行的优化。但是这里并没有起到实质性的作用,因为往往表单中隐藏的元素其实并不是很多,想要得到更大的提升应该是把页面中显示出来但是又不需要验证的标签进行过滤,真正做到只去check需要check的标签元素。这里网上有一种方法就是给每个不需要Check的元素标签添加一个类似于“class='validate-ignore'”这样的类,然后在elements()方法中把这样不需要验证的元素也过滤掉。这种做法我并没有去实践,因为项目中表单太多,这样一个个去添加新的class显的有点不现实。有兴趣的朋友可以去研究一下。
2.showErrors().
这个方法之所以会花销大量的时间。因为这个方法会使得HTML DOM树发生改变,来显示和修改错误或正确的提示信息。
原生的showErrors方法如下
默认页面中每个需要验证的elment都会经过这个else分支去执行defaultShowErrors()函数,而这个函数就是改变DOM树结构的入口。所以我们在这里新增一个判断的逻辑会提升不少的时间。新增判断如下:
showErrors: function( errors ) {
if ( errors ) {
var validator = this; // Add items to error list and map
$.extend( this.errorMap, errors );
this.errorList = $.map( this.errorMap, function( message, name ) {
return {
message: message,
element: validator.findByName( name )[ 0 ]
};
} ); // Remove items from success list
this.successList = $.grep( this.successList, function( element ) {
return !( element.name in errors );
} );
}
if ( this.settings.showErrors ) {
this.settings.showErrors.call( this, this.errorMap, this.errorList );
} else {
var anyElementsNeedUpdate = false; //参数表示是否需要去更新DOM树中的元素
for (var i = 0; i < this.errorList.length; i++) {
if (!$(this.errorList[i].element).hasClass(this.settings.errorClass)) {
anyElementsNeedUpdate = true;//1.当之前验证有错误的元素已经修改正确即没有了这个errorClass,需要去更新element
break;
}
} if (!anyElementsNeedUpdate) {
for (var i = 0; i < this.successList.length; i++) {
if ($(this.successList[i]).hasClass(this.settings.errorClass)) {
anyElementsNeedUpdate = true;//2.当之前验证成功的元素现在含有这个errorClass,需要去更新element
break;
}
}
} if (anyElementsNeedUpdate) {//如果有上面两种情况之一都需要去更新DOM元素,否则不应该去调用defaultShowErrors();
this.defaultShowErrors();
}
}
},
从这个可以明显的看出,checkForm()函数时间没有太大的变化。但是showErrors()时间变成了之前的十分之一。
经过测试这个修改对验证功能是没有影响的,而且性能也提升了不少。
参考:http://stackoverflow.com/questions/5542014/jquery-validate-large-forms-script-running-slowly。
jQuery.Validate.js验证大表单的优化的更多相关文章
- 使用jquery.validate.js插件进行表单里控件的验证
jsp中具体实现的代码: <%@ page language="java" contentType="text/html; charset=UTF-8" ...
- jquery.validate.js之自定义表单验证规则
<html> <head> <meta http-equiv="Content-Type" content="text/html; char ...
- jquery.validate.js 验证表单时,在IE当中未验证就直接提交的原因
jquery.validate.js 验证表单时,在IE当中未验证就直接提交的原因 今天利用了jquery.validate.js来验证表单,发现在火狐.谷歌浏览器当中都可以进行验证,但是在IE系列浏 ...
- js验证form表单示例
js验证form表单示例 检测测试了js表单验证,无jQuery(简单的功能有时无需jQuery版本) js代码如下: <script type="text/javascript& ...
- 第十七篇 JS验证form表单
JS验证form表单 这节课做一个实际的,项目里会遇到的东西,例如登录页面,我们输入‘用户名’和‘密码’或者‘手机号’还有‘验证码’等等,它都会做一个前端验证,比如验证码,是6位有效数字组成,那么 ...
- jQuery Validate【强大的表单验证】
一.引入菜鸟教程提供的 1.14.0 版本下载地址:http://static.runoob.com/download/jquery-validation-1.14.0.zip <script ...
- 使用jquery validate结合zui作表单验证
1.引入jquery validate和zui <!-- jQuery (ZUI中的Javascript组件依赖于jQuery) --> <script src="${_b ...
- jquery validate如何不提交表单就做验证(ajax提交数据)
if($("#FromID").valid()){ $.ajax({ type:'post', url:'/CampaignOrderRelations/save', data:{ ...
- jquery.form.js(ajax表单提交)
Form插件地址: 官方网站:http://malsup.com/jQuery/form/ 翻译地址:http://www.aqee.net/docs/jquery.form.plugin/jquer ...
随机推荐
- Excel公式
多个IF =IF(ISNUMBER(SEARCH("lz",E7)),"lz", IF(ISNUMBER(SEARCH("zch",E7)) ...
- 树上的构造 树分治+树重心的性质 Codeforces Round #190 (Div. 2) E
http://codeforces.com/contest/322/problem/E E. Ciel the Commander time limit per test 1 second memor ...
- Android Studio 更新失败的解决办法
编辑$ANDROID_STUDIO_HOME/bin/ 下的 studio.exe.vmoptions(如果系统用的Ubuntu,文件应该是studio.vmoptions或者如果是64位系统,应该是 ...
- 一张图搞懂Spring bean的完整生命周期
一张图搞懂Spring bean的生命周期,从Spring容器启动到容器销毁bean的全过程,包括下面一系列的流程,了解这些流程对我们想在其中任何一个环节怎么操作bean的生成及修饰是非常有帮助的. ...
- 【CodeForces】901 B. GCD of Polynomials
[题目]B. GCD of Polynomials [题意]给定n,要求两个最高次项不超过n的多项式(第一个>第二个),使得到它们GCD的辗转次数为n.n<=150. [算法]构造 [题解 ...
- phpcms模板
cms的样式有很多种,我们学习的是phpcms,这些cms都是大同小异,学会了一种就可以使用其它的cms. PHPCMS是一款网站管理软件.该软件采用模块化开发,支持多种分类方式,使用它可方便实现个性 ...
- 去除UITableView多余的seperator
UIView *v = [[UIView alloc] initWithFrame:CGRectZero]; [tableView setTableFooterView:v]; [v release] ...
- 打表找规律C - Insertion Sort Gym - 101955C
题目链接:https://cn.vjudge.net/contest/273377#problem/C 给你 n,m,k. 这个题的意思是给你n个数,在对前m项的基础上排序的情况下,问你满足递增子序列 ...
- python基础之常用的高阶函数
前言 高阶函数指的是能接收函数作为参数的函数或类:python中有一些内置的高阶函数,在某些场合使用可以提高代码的效率. map() map函数可以把一个迭代对象转换成另一个可迭代对象,不过在pyth ...
- React Native 快速入门之认识Props和State
眼下React Native(以后简称RN)越来越火,我也要投入到学习当中.对于一个前端来说,还是有些难度.因为本人觉得这是一个App开发的领域,自然是不同.编写本文的时候,RN的版本为0.21.0. ...