最近在项目中有遇到一个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验证大表单的优化的更多相关文章

  1. 使用jquery.validate.js插件进行表单里控件的验证

    jsp中具体实现的代码: <%@ page language="java" contentType="text/html; charset=UTF-8" ...

  2. jquery.validate.js之自定义表单验证规则

    <html> <head> <meta http-equiv="Content-Type" content="text/html; char ...

  3. jquery.validate.js 验证表单时,在IE当中未验证就直接提交的原因

    jquery.validate.js 验证表单时,在IE当中未验证就直接提交的原因 今天利用了jquery.validate.js来验证表单,发现在火狐.谷歌浏览器当中都可以进行验证,但是在IE系列浏 ...

  4. js验证form表单示例

    js验证form表单示例 检测测试了js表单验证,无jQuery(简单的功能有时无需jQuery版本) js代码如下:   <script type="text/javascript& ...

  5. 第十七篇 JS验证form表单

    JS验证form表单   这节课做一个实际的,项目里会遇到的东西,例如登录页面,我们输入‘用户名’和‘密码’或者‘手机号’还有‘验证码’等等,它都会做一个前端验证,比如验证码,是6位有效数字组成,那么 ...

  6. jQuery Validate【强大的表单验证】

    一.引入菜鸟教程提供的 1.14.0 版本下载地址:http://static.runoob.com/download/jquery-validation-1.14.0.zip <script ...

  7. 使用jquery validate结合zui作表单验证

    1.引入jquery validate和zui <!-- jQuery (ZUI中的Javascript组件依赖于jQuery) --> <script src="${_b ...

  8. jquery validate如何不提交表单就做验证(ajax提交数据)

    if($("#FromID").valid()){ $.ajax({ type:'post', url:'/CampaignOrderRelations/save', data:{ ...

  9. jquery.form.js(ajax表单提交)

    Form插件地址: 官方网站:http://malsup.com/jQuery/form/ 翻译地址:http://www.aqee.net/docs/jquery.form.plugin/jquer ...

随机推荐

  1. 二叉树系列 - 求两节点的最低公共祖先,例 剑指Offer 50

    前言 本篇是对二叉树系列中求最低公共祖先类题目的讨论. 题目 对于给定二叉树,输入两个树节点,求它们的最低公共祖先. 思考:这其实并不单单是一道题目,解题的过程中,要先弄清楚这棵二叉树有没有一些特殊的 ...

  2. extjs6需要引入文件

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  3. 【机器学习】K-邻近算法的python 实现

    #!/usr/bin/python # -*- coding: utf-8 -*- from numpy import * import operator def createDataSet(): ' ...

  4. POJ 2318/2398 叉积性质

    2318 2398 题意:给出n条线将一块区域分成n+1块空间,再给出m个点,询问这些点在哪个空间里. 思路:由于只要求相对位置关系,而对具体位置不关心,那么易使用叉积性质得到相对位置关系(左侧/右侧 ...

  5. 2015/9/21 Python基础(17):绑定和方法调用

    绑定和方法调用现在我们需要再次阐述Python中绑定(binding)的概念,它主要与方法调用相关联.方法是类内部定义的函数,这意味着方法是类属性而不是实例属性.其次,方法只有在其所属的类拥有实例时, ...

  6. javascript在IE下不能用 trim函数解决方法

    javascript 的trim 函数在firefox 下面使用没有问题 <script language="javascript"> var test1 = &quo ...

  7. unity3d 资源文件从MAX或者MAYA中导出的注意事项

    unity3d 资源文件从MAX或者MAYA中导出的注意事项     1.首先,Unity3d 中,导出带动画的资源有2种导出方式可以选择:    1) 导出资源时,只导出一个文件,保留模型,骨骼和所 ...

  8. CRF++进行中文分词实例

    工具包:https://taku910.github.io/crfpp/#tips 语料:http://sighan.cs.uchicago.edu/bakeoff2005/ 安装: 1)下载linu ...

  9. 判断Selenium加载完成

    How do you make Selenium 2.0 wait for the page to load? You can also check pageloaded using followin ...

  10. MessageDigest类实现md5加密

    项目中用到的md5工具类: package com.mall.util; import org.springframework.util.StringUtils; import java.securi ...