jQuery.Validate.js在Form标签很多的时候验证速度慢的处理。

最近在项目中有遇到一个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

时间: 2025-01-01 01:19:52

jQuery.Validate.js在Form标签很多的时候验证速度慢的处理。的相关文章

jquery.validate.js【简单实用的表单验证框架】

在线演示1 本地下载 原文链接:http://www.gbtags.com/gb/share/5749.htm 最近在做用户登录.注册.以及用户中心...然后之前在慕课网学的jquery.validate用得着地方了,根据自己需求进行了细节修改,重要是样式方面吧. 第一次发表这些,说得不好不要介意,开始吧.首先: $("#form").validate({ //在这里面编辑 }); 验证的时候常常需要调试,该框架内置了一个方法,如下: debug:true, //调试模式(并不会提交)

jquery.validate.js【简单实用的表单验证框架】【进阶版】

这个是这个插件的官网和我找到的一个中文博客.(虽然插件的名字叫做jquery.validte.js,但其实,这个插件的名字叫jquery validation). 基础的用法可以去看冷子欲的文章或者上面的博客,我这里就不详细介绍了. 首先最重要的一点,所有要验证的域都要在form里,同时这些域都要有name属性. 详细内容请见原文链接:http://www.gbtags.com/gb/share/5765.htm 1. 默认validate参数的初始化: 这个插件如果要用,肯定很多页面都会用到,

jQuery验证控件jquery.validate.js使用说明+中文API

官网地址:http://bassistance.de/jquery-plugins/jquery-plugin-validation jQuery plugin: Validation 使用说明 转载自:http://blog.sina.com.cn/s/blog_608475eb0100h3h1.html 一导入js库<script src="../js/jquery.js" type="text/javascript"></script>

jQuery验证空间jquery.validate.js使用说明+中文API

--------转载自http://www.cnblogs.com/hejunrex/archive/2011/11/17/2252193.html jQuery plugin: Validation 使用说明 官网地址:http://bassistance.de/jquery-plugins/jquery-plugin-validation 转载自:http://blog.sina.com.cn/s/blog_608475eb0100h3h1.html 一.导入js库 <script src=

jQuery验证控件jquery.validate.js使用说明+中文API - Rex.He - 博客园

官网地址:http://bassistance.de/jquery-plugins/jquery-plugin-validation jQuery plugin: Validation 使用说明 转载自:http://blog.sina.com.cn/s/blog_608475eb0100h3h1.html 一导入js库 <script src="../js/jquery.js" type="text/javascript"></script>

jQuery验证控件jquery.validate.js的使用介绍

官网地址:http://bassistance.de/jquery-plugins/jquery-plugin-validation jQuery plugin: Validation 使用说明 转载自:http://blog.sina.com.cn/s/blog_608475eb0100h3h1.html 一导入js库<script src="../js/jquery.js" type="text/javascript"></script>

jQuery验证控件jquery.validate.js使用说明+中文API (转)

官网地址:http://bassistance.de/jquery-plugins/jquery-plugin-validation jQuery plugin: Validation 使用说明 转载自:http://blog.sina.com.cn/s/blog_608475eb0100h3h1.html 一导入js库 <script src="../js/jquery.js" type="text/javascript"> </script&g

Jquery.validate.js表单验证插件的使用

作为一个网站web开发人员,以前居然不知道还有表单验证这样好呀的插件,还在一行行写表单验证,真是后悔没能早点知道他们的存在. 最近公司不忙,自己学习一些东西的时候,发现了validation的一个实例讲解应用.it's perfect. 首先记录一些使用过程中,爱犯的错误: 1>忘记给表单form添加id属性 2>input这些表单标签必须id属性和name属性名字一样.例如:<input type="text" id="name" name=&q

jQuery插件之验证控件jquery.validate.js

今天学习一下jQuery.Validate插件,为便于日后翻阅查看和广大博客园园友共享,特记于此. 本博客转载自:jQuery Validate jQuery Validate 插件为表单提供了强大的验证功能,让客户端表单验证变得更简单,同时提供了大量的定制选项,满足应用程序各种需求.该插件捆绑了一套有用的验证方法,包括 URL 和电子邮件验证,同时提供了一个用来编写用户自定义方法的 API.所有的捆绑方法默认使用英语作为错误信息,且已翻译成其他 37 种语言. 该插件是由 Jörn Zaeff