jQuery实现高度灵活的表单验证功能示例【无UI】


Posted in jQuery onApril 30, 2020

本文实例讲述了jQuery实现高度灵活的表单验证功能。分享给大家供大家参考,具体如下:

表单验证是前端开发过程中常见的一个需求,产品需求、业务逻辑的不同,表单验证的方式方法也有所区别。而最重要的是我们要清楚,表单验证的核心原则是——错误信息提示准确,并且尽可能少的打扰/干扰用户的输入和体验。

该插件依赖于jQuery,demo地址:https://github.com/CaptainLiao/zujian/tree/master/validator

基于以上原则,个人总结出表单验证的通用方法论:

为了使开发思路更加清晰,我将表单验证的过程分为两步:第一步,用户输入完验证当前输入的有效性;第二步,表单提交时验证整个表单。考虑如下布局:

<form action="">
  <ul>
    <li><label for="username">用户名</label>
      <input type="text" name="username" id="username" placeholder="用户名"/></li>
    <li>
      <label for="password">密码</label>
      <input type="text" name="password" id="password" placeholder="密码"/>
    </li>
    <li>
      <label for="password">确认密码</label>
      <input type="text" name="password2" id="password-confirm" placeholder="确认密码"/>
    </li>
    <li>
      <label for="phone">手机</label>
      <input type="text" name="mobile" id="phone"/>
    </li>
    <li>
      <label for="email">邮箱</label>
      <input type="text" name="email" id="email"/>
    </li>
  </ul>

  <button type="submit" id="submit-btn">提交</button>

</form>

一个较为通用的JS验证版本如下:

(function (window, $, undefined) {
  /**
   * @param {String}    $el       表单元素
   * @param {[Array]}    rules      自定义验证规则
   * @param {[Boolean]}   isCheckAll   表单提交前全文验证
   * @param {[Function]}  callback    全部验证成功后的回调
   * rules 支持四个字段:name, rule, message, equalTo
   */
  function Validator($el, rules, isCheckAll, callback) {
    var required = 'required';
    var params = Array.prototype.slice.call(arguments);
    this.$el = $el;
    this._rules = [
      {// 用户名
        username: required,
        rule: /^[\u4e00-\u9fa5\w]{6,12}$/,
        message: '不能包含敏感字符'
      }, {// 密码
        password: required,
        rule: /^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z_@]{6,20}$/,
        message: '只支持数字字母下划线,且不为纯数字或字母'
      }, {// 重复密码
        password2: required,
        rule: /^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z_@]{6,20}$/,
        message: '只支持数字字母下划线,且不为纯数字或字母',
        equalTo: 'password'
      }, {// 手机
        mobile: required,
        rule: /^1[34578]\d{9}$/,
        message: '请输入有效的手机号码'
      }, {// 验证码
        code : required,
        rule: /^\d{6}$/,
        message: '请输入6位数字验证码'
      }, {// 邮箱
        email : required,
        rule: /^[A-Za-z0-9\u4e00-\u9fa5]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/,
        message: '请输入正确的邮箱'
      }
    ];
    this.isCheckAll = false;
    this.callback = callback;
    // 合并参数
    this._rules = this._rules.concat(params[1]);
    if(params[2]) {
      if(typeof params[2] == 'function') {
        this.callback = params[2];
      }else {// 提交表单时是否开启全部验证
        this.isCheckAll = params[2];
      }
    }
    // 用于存储合去重后的参数
    this.rules = [];
  }

  Validator.prototype._getKey = function (obj) {
    var k = '';
    for(var key in obj) {
      if(obj.hasOwnProperty(key)) {
        if( key !== 'rule' && key !== 'message' && key !== 'equalTo') {
          k = key;
        }
      }
    }
    return k;
  };
  /**
   * 数组对象重复数据进行合并,后面的覆盖前面的
   */
  Validator.prototype.filterRules = function (arrObj) {
    var _this = this,
      h = {},
      res = [],
      arrObject = this._rules;
    $.each(arrObject, function (i, item) {
      var k = _this._getKey(item);
      try {
        if(!h[k] && h[k] !== 0) {
          h[k] = i;
          res.push(item);
        }else {
          res[h[k]] = $.extend(res[h[k]], item);
        }
      }catch(e) {
        throw new Error('不是必填')
      }
    });
    this.rules = res;
  };

  Validator.prototype.check = function () {
    var _this = this;
    $.each(_this.rules, function (i, item) {
      var key = _this._getKey(item),
        reg = item.rule,
        equalTo = item.equalTo,
        errMsg = item.message;

      _this.$el.find('[name='+key+']')
        .on('blur', function () {
          var $this = $(this),
            errorMsg = '',
            val = $this.val(),
            ranges = reg.toString().match(/(\d*,\d*)/),
            range = '',
            min = 0,
            max = 0,
            placeholderTxt = $(this).attr("placeholder") ? $(this).attr("placeholder") : '信息';

          // 定义错误提示信息
          if(val && val != 'undefined') { // 值不为空

            if(ranges) { // 边界限定
              range = ranges[0];
              min = range.split(',')[0] ? range.split(',')[0].trim() : 0;
              max = range.split(',')[1] ? range.split(',')[1].trim() : 0;
              if(val.length < min || val.length > max) { // 处理边界限定的情况
                if(min && max) {
                  errorMsg = '<span class="error-msg">请输入'+min+'-'+max+'位'+placeholderTxt+'</span>';
                }else if(min) {
                  errorMsg = '<span class="error-msg">最少输入'+min+'位'+placeholderTxt+'</span>';
                }else if(max) {
                  errorMsg = '<span class="error-msg">最多输入'+max+'位'+placeholderTxt+'</span>';
                }
              }else { // 边界正确但匹配错误
                errorMsg = '<span class="error-msg">'+errMsg+'</span>';

              }
            }else { // 没有边界限定
              errorMsg = '<span class="error-msg">'+errMsg+'</span>';
            }

            if(equalTo) {
              var equalToVal = _this.$el.find('[name='+equalTo+']').val();
              if(val !== equalToVal) {
                errorMsg = '<span class="error-msg">两次输入不一致,请重新输入</span>';
              }
            }

          } else { // 值为空
            errorMsg = '<span class="error-msg">请输入'+placeholderTxt+'</span>'
          }
          if($('.error-msg').length > 0) return;

          // 验证输入,显示提示信息
          if(!reg.test(val) || (equalTo && val !== equalToVal)) {
            if($this.siblings('.error-msg').length == 0) {
              $this.after(errorMsg)
                .siblings('.error-msg')
                .hide()
                .fadeIn();
            }
          }else {
            $this.siblings('.error-msg').remove();
          }
        })
        .on('focus', function () {
          $(this).siblings('.error-msg').remove();
        })
    });

  };
  Validator.prototype.checkAll = function () {
    var _this = this;
    if(_this.isCheckAll) {
      _this.$el.find('[type=submit]')
        .click(function () {
          _this.$el.find('[name]').trigger('blur');
          if($('.error-msg').length > 0) {
            console.log('有错误信息');
            return false;
          }else {
            console.log('提交成功');
            _this.callback();
          }
        });
      return false;
    }
  };
  Validator.prototype.init = function () {
    this.filterRules();
    this.check();
    this.checkAll();
  };
  $.fn.validator = function (rules, isCheckAll, callback) {
    var validate = new Validator(this, rules, isCheckAll, callback);
    return validate.init();
  };
})(window, jQuery, undefined);

你可以这样使用:

var rules = [
    {// 用户名
      username: 'required',
      rule: /^[\u4e00-\u9fa5\d]{6,12}$/,
      message: '只支持数字loo2222'
    },
    {// 密码
      password: 'required',
      rule: /^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z_@]{6,20}$/,
      message: 'mimmimmia'
    },
    {// 重复密码
      password2: 'required',
      rule: /^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z_@]{6,20}$/,
      message: '只支持数字字母下划线,不能为纯数字或字母2222',
      equalTo: 'password'
    },
    {// 座机
      telephone : 'required',
      rule: /^[A-Za-z0-9\u4e00-\u9fa5]+@[a-zA-Z0-9_-]+(.[a-zA-Z0-9_-]+)+$/,
      message: '请输入正确的座机'
    }
  ];
  $('form').validator(rules, true)
jQuery 相关文章推荐
jQuery实现Select下拉列表进行状态选择功能
Mar 30 jQuery
jQuery获取table下某一行某一列的值实现代码
Apr 07 jQuery
node.js+jQuery实现用户登录注册AJAX交互
Apr 28 jQuery
简述jQuery Easyui一些用法
Aug 01 jQuery
详解jquery选择器的原理
Aug 01 jQuery
jQuery简单实现对数组去重及排序操作实例
Oct 31 jQuery
简单实现jquery隔行变色
Nov 09 jQuery
jQuery实现简单的下拉菜单导航功能示例
Dec 07 jQuery
jQuery实现动态控制页面元素的方法分析
Dec 20 jQuery
jQuery实现动态显示select下拉列表数据的方法
Feb 05 jQuery
jquery实现动态添加附件功能
Oct 23 jQuery
JavaScript前端页面搜索功能案例【基于jQuery】
Jul 10 jQuery
jQuery插件simplePagination的使用方法示例
Apr 28 #jQuery
jquery检测上传文件大小示例
Apr 26 #jQuery
jquery实现轮播图特效
Apr 12 #jQuery
用jQuery实现抽奖程序
Apr 12 #jQuery
jquery实现两个div中的元素相互拖动的方法分析
Apr 05 #jQuery
jQuery 图片查看器插件 Viewer.js用法简单示例
Apr 04 #jQuery
jQuery实现鼠标放置名字上显示详细内容气泡提示框效果的方法分析
Apr 04 #jQuery
You might like
thinkPHP5框架设置404、403等http状态页面的方法
2018/06/05 PHP
phpQuery采集网页实现代码实例
2020/04/02 PHP
JavaScript this调用规则说明
2010/03/08 Javascript
风吟的小型JavaScirpt库 (FY.JS).
2010/03/09 Javascript
jquery EasyUI的formatter格式化函数代码
2011/01/12 Javascript
鼠标放在图片上显示大图的JS代码
2013/03/26 Javascript
Jquery实现点击切换图片并隐藏显示内容(2种方法实现)
2013/04/11 Javascript
js隐式全局变量造成的bug示例代码
2014/04/22 Javascript
将HTML格式的String转化为HTMLElement的实现方法
2014/08/07 Javascript
JavaScript中的6种运算符总结
2014/10/16 Javascript
详解jQuery移动页面开发中的ui-grid网格布局使用
2015/12/03 Javascript
详解maxlength属性在textarea里奇怪的表现
2015/12/27 Javascript
阿里巴巴技术文章分享 Javascript继承机制的实现
2016/01/14 Javascript
js 求时间差的实现代码
2016/04/26 Javascript
移动端横屏的JS代码(beta)
2016/05/16 Javascript
JS给Array添加是否包含字符串的简单方法
2016/10/29 Javascript
Vue数据双向绑定原理及简单实现方法
2018/05/18 Javascript
前端天气插件tpwidget使用方法详解
2019/06/24 Javascript
Vue Render函数创建DOM节点代码实例
2020/07/08 Javascript
Python探索之URL Dispatcher实例详解
2017/10/28 Python
Python使用遗传算法解决最大流问题
2018/01/29 Python
python3+PyQt5实现柱状图
2018/04/24 Python
python实现公司年会抽奖程序
2019/01/22 Python
Python 中@property的用法详解
2020/01/15 Python
Python 实现二叉查找树的示例代码
2020/12/21 Python
深入剖析webstorage[html5的本地数据处理]
2016/07/11 HTML / CSS
整理HTML5中表单的常用属性及新属性
2016/02/19 HTML / CSS
New Balance英国官方网站:始于1906年,百年慢跑品牌
2016/12/07 全球购物
英国女性化妆品收纳和家具网站:Beautify
2019/12/07 全球购物
PyQt QMainWindow的使用示例
2021/03/24 Python
大学军训感言300字
2014/03/09 职场文书
小摄影师教学反思
2014/04/27 职场文书
刑事法律意见书
2015/06/04 职场文书
工伤事故赔偿协议书
2015/08/06 职场文书
CSS实现多个元素在盒子内两端对齐效果
2021/03/30 HTML / CSS
解决SpringCloud Feign传对象参数调用失败的问题
2021/06/23 Java/Android