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.ajax向后台传递数组问题的解决方法
May 12 jQuery
jQuery滑动到底部加载下一页数据的实例代码
May 22 jQuery
基于jQuery封装的分页组件
Jun 26 jQuery
浅谈jQuery框架Ajax常用选项
Jul 08 jQuery
JQuery 获取Dom元素的实例讲解
Jul 08 jQuery
基于jQuery实现定位导航位置效果
Nov 15 jQuery
jQuery实现的淡入淡出与滑入滑出效果示例
Apr 18 jQuery
jQuery实现表单动态加减、ajax表单提交功能
Jun 08 jQuery
jQuery实现简单复制json对象和json对象集合操作示例
Jul 09 jQuery
基于jQuery ztree实现表格风格的树状结构
Aug 31 jQuery
jquery+ajax实现上传图片并显示上传进度功能【附php后台接收】
Jun 06 jQuery
使用jquery实现轮播图效果
Jan 02 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
缅甸的咖啡简史
2021/03/04 咖啡文化
php入门学习知识点八 PHP中for循环基本应用之九九乘法口绝表
2011/07/14 PHP
php操作mysql数据库的基本类代码
2014/02/25 PHP
在WordPress中使用wp_count_posts函数来统计文章数量
2016/01/05 PHP
PHP实现适用于文件内容操作的分页类
2016/06/15 PHP
二行代码解决全部网页木马
2008/03/28 Javascript
解决jquery操作checkbox火狐下第二次无法勾选问题
2014/02/10 Javascript
javascript数据类型示例分享
2015/01/19 Javascript
jQuery读取XML文件内容的方法
2015/03/09 Javascript
jQuery中$this和$(this)的区别介绍(一看就懂)
2015/07/06 Javascript
JS判断来路是否是百度等搜索索引进行弹窗或自动跳转的实现代码
2016/10/09 Javascript
JS实现身份证输入框的输入效果
2017/08/21 Javascript
JQuery元素快速查找与操作
2018/04/22 jQuery
vue.js 实现输入框动态添加功能
2018/06/25 Javascript
浅谈微信小程序之官方UI框架we-ui使用教程
2018/08/20 Javascript
Vue 幸运大转盘实现思路详解
2019/05/06 Javascript
Bootstrap 时间日历插件bootstrap-datetimepicker配置与应用小结
2019/05/28 Javascript
Angular中innerHTML标签的样式不起作用的原因解析
2019/06/18 Javascript
JS常用正则表达式超全集(密码强度校验,金额校验,IE版本,IPv4,IPv6校验)
2020/02/03 Javascript
微信公众号网页分享功能开发的示例代码
2020/05/27 Javascript
Python中特殊函数集锦
2015/07/27 Python
在python中以相同顺序shuffle两个list的方法
2018/12/13 Python
Python实现将多个空格换为一个空格.md的方法
2018/12/20 Python
Python零基础入门学习之输入与输出
2019/04/03 Python
使用python写一个自动浏览文章的脚本实例
2019/12/05 Python
解决Keras 与 Tensorflow 版本之间的兼容性问题
2020/02/07 Python
使用pth文件添加Python环境变量方式
2020/05/26 Python
python实现AdaBoost算法的示例
2020/10/03 Python
Python控制鼠标键盘代码实例
2020/12/08 Python
Python非单向递归函数如何返回全部结果
2020/12/18 Python
使用canvas绘制超炫时钟
2014/12/17 HTML / CSS
国际领先的在线时尚服装和配饰店:DressLily
2019/03/03 全球购物
泰国Robinson百货官网:购买知名品牌的商品
2020/02/08 全球购物
华为消费者德国官方网站:HUAWEI德国
2020/11/03 全球购物
甜品店的创业计划书范文
2014/01/02 职场文书
乡镇遵守党的政治纪律情况对照检查材料
2014/09/26 职场文书