发现了jQuery Validation Pluginv1.13.1有一个小BUG。
需求实现是:一个输入框验证不通过错误提示信息显示在label中,此时使用.error样式。当验证通过,通过设置option中的success为function来操作,remove掉.error样式,add上.valid样式。
可是发现如果在验证通过的情况下,不停地在输入框中onblur,那么会不停地新增显示错误信息的label,导致不停新增验证通过的样式。
具体看下图:
直接提交,验证不通过,正常
填写一个正确格式的手机号码,正常
然后手贱,在手机号码的输入框中做了几次onblur操作,尼玛!!!坑爹呢这是??!!
我设置success的代码好简单的啊,这就挂了?!!
success: function (error, element) { error.removeClass("error").addClass("valid"); }
然后没辙,只能翻大神的源码看了。后来发现问题出现在以下errors函数的代码上:
errors: function() { var errorClass = this.settings.errorClass.split( " " ).join( "." ); return $( this.settings.errorElement + "." + errorClass, this.errorContext ); },
可以看出,这个函数拿error的显示元素(就是errorElement)就是使用.error进行抓取,但是,我的代码操作时候已经将.error去除了。为什么去除?因为已经验证通过了,不想label里面还有一个.error样式啊(有强迫症的人伤不起)
那么errors没有抓到显示错误的元素会怎样,当然是创建一个了。那么问题找到了,我改了两处来处理这种情况
1.修改errors函数,让他通过id属性来抓取显示错误的元素
errors: function( element ) { return $( this.settings.errorElement + "#" + this.idOrName(element) + "-error", this.errorContext ); },
之所以敢大胆地使用ID属性来抓取显示错误元素,是因为源码中创建这个元素是都会必定添加ID,不信?看源码:
showLabel: function( element, message ) { var place, group, errorID, error = this.errorsFor( element ), elementID = this.idOrName( element ), describedBy = $( element ).attr( "aria-describedby" ); if ( error.length ) { // refresh error/success class error.removeClass( this.settings.validClass ).addClass( this.settings.errorClass ); // replace message on existing label error.html( message ); } else { // create error element error = $( "<" + this.settings.errorElement + ">" ) .attr( "id", elementID + "-error" ) //看到了没看到了没? .addClass( this.settings.errorClass ) .html( message || "" ); ......