如何为jQuery Validate添加基于触发事件的自定义验证规则?
jQuery Validate 自定义规则按触发事件执行不同逻辑的优化实现
需求描述
需要给jQuery Validate添加自定义规则,根据触发验证的事件(submit/keyup等)执行不同检查操作,同时保留字段原有默认规则的触发逻辑:
- submit事件触发时:
- AJAX校验邮箱是否已存在
- 邮箱域名匹配已知域名时给出提示(弹窗或临时阻止验证)
- keyup事件触发时:
- 邮箱域名匹配已知域名时给出被动提示
- 检测到常见拼写错误时提示正确写法
当前实现(全局变量存储事件)
目前用全局变量存储触发事件,但实现不够优雅:
var validationEvent; $('#myForm').submit(function(event) { event.stopPropagation(); event.preventDefault(); validationEvent = event; }).validate({ onkeyup: function(element, event) { validationEvent = event; $(element).valid(); }, rules: { email: { required: true, myCustomFunction: true, email: true } } });
对应的自定义方法:
$.validator.addMethod("myCustomFunction", function(value, element, params) { if (validationEvent == undefined) { return true; } if (validationEvent.type == "submit") { // 执行submit对应的逻辑 } if (validationEvent.type == "keyup") { // 执行keyup对应的逻辑 } });
理想状态是直接将事件作为规则参数传入,示例如下:
$('#myForm').validate({ rules: { email: { myCustomFunction: event } } }); $.validator.addMethod("myCustomFunction", function(value, element, params) { if (params.type == "submit") { // 执行submit逻辑 } });
优化方案
方案1:利用元素data属性传递事件
不需要全局变量,在触发验证的回调中将事件存入目标元素的data属性,自定义规则内直接读取:
$('#myForm').validate({ onkeyup: function(element, event) { $(element).data('validation-trigger-event', event); $(element).valid(); }, submitHandler: function(form, event) { $('[name="email"]', form).data('validation-trigger-event', event); if ($(form).valid()) { form.submit(); } }, rules: { email: { required: true, myCustomFunction: true, email: true } } });
自定义方法:
$.validator.addMethod("myCustomFunction", function(value, element, params) { const triggerEvent = $(element).data('validation-trigger-event'); if (!triggerEvent) return true; switch(triggerEvent.type) { case 'submit': // 执行AJAX检查邮箱存在、域名提示等逻辑 console.log('submit触发自定义验证'); break; case 'keyup': // 执行域名被动提示、拼写错误检查等逻辑 console.log('keyup触发自定义验证'); break; } // 异步验证需使用remote规则或手动处理异步逻辑,此处示例返回同步结果 return true; });
方案2:拆分规则,按事件绑定专属逻辑
将submit和keyup的逻辑拆分为两个独立自定义规则,通过onkeyup和submitHandler分别触发,避免事件判断:
// 针对submit的自定义规则 $.validator.addMethod("emailSubmitCheck", function(value, element) { // AJAX检查邮箱存在+域名提示逻辑 console.log('submit触发邮箱检查'); return true; }); // 针对keyup的自定义规则 $.validator.addMethod("emailKeyupCheck", function(value, element) { // 域名提示+拼写检查逻辑 console.log('keyup触发邮箱检查'); return true; }); $('#myForm').validate({ onkeyup: function(element, event) { if ($(element).attr('name') === 'email') { $(element).rules('add', { emailKeyupCheck: true }); } $(element).valid(); if ($(element).attr('name') === 'email') { $(element).rules('remove', 'emailKeyupCheck'); } }, submitHandler: function(form) { $('[name="email"]', form).rules('add', { emailSubmitCheck: true }); if ($(form).valid()) { form.submit(); } $('[name="email"]', form).rules('remove', 'emailSubmitCheck'); }, rules: { email: { required: true, email: true } } });
方案3:扩展jQuery Validate验证上下文
重写jQuery Validate的内部方法,将触发事件传入验证实例的上下文,注意版本兼容性:
// 重写onkeyup方法,传入事件到验证上下文 const originalOnkeyup = $.validator.prototype.onkeyup; $.validator.prototype.onkeyup = function(element, event) { this.currentTriggerEvent = event; originalOnkeyup.call(this, element, event); delete this.currentTriggerEvent; }; // 重写submit处理逻辑,传入事件 const originalSubmitHandler = $.validator.prototype.submitHandler; $.validator.prototype.submitHandler = function(form, event) { this.currentTriggerEvent = event; if (this.form()) { originalSubmitHandler.call(this, form, event); } delete this.currentTriggerEvent; }; // 自定义规则 $.validator.addMethod("myCustomFunction", function(value, element, params) { const triggerEvent = this.currentTriggerEvent; if (!triggerEvent) return true; if (triggerEvent.type === 'submit') { // 执行submit专属逻辑 } else if (triggerEvent.type === 'keyup') { // 执行keyup专属逻辑 } return true; }); // 初始化表单验证 $('#myForm').validate({ rules: { email: { required: true, myCustomFunction: true, email: true } } });
注意:若涉及异步验证(如AJAX检查邮箱存在),需使用jQuery Validate的
remote规则或手动处理异步逻辑,避免验证结果返回不及时导致的问题。
内容的提问来源于stack exchange,提问作者Gugusteh
相关产品推荐
相关产品推荐

