javascript将异步校验表单改写为同步表单


Posted in Javascript onJanuary 27, 2015

同步表单校验的缺点

响应错误信息时,需要重新加载整个页面(虽然有缓存,客户端仍然需要通过http协议对比每个文件是否有更新,以保持文件最新)
服务器响应错误以后,用户之前所输入的信息全部丢失了,用户需要从头开始填写(部分浏览器帮我们缓存了这些数据)

异步校验表单的初衷

提升用户体验
最大化减少网络请求,减轻服务器压力
下面我们看一个常见的异步表单校验(校验工号在后台是否存在,存在为有效工号)

javascript将异步校验表单改写为同步表单

校验工号

var BASE_PATH = '${rc.contextPath}';

var $workerIdInput = $('#workerIdInput');

var $workerIdError = $('#workerIdError');

//标识用户输入的工号是否正确

var isWorkerIdCorrect = false;

var ERROR_WORKER_ID_IS_NULL = "员工工号不能为空";

var ERROR_WORKER_ID_IS_NOT_CORRECT = "请输入有效的员工工号";

//显示错误信息

function showWorkerIdError(errorMessage) {

  $workerIdError.html(errorMessage);

  $workerIdError.show();

}

//隐藏错误信息

$workerIdInput.on('keydown', function() {

  $workerIdError.hide();

});

//将上次输入的工号保存起来

$workerIdInput.on('focus', function() {

  var workerId = $.trim($(this).val());

  $(this).data('before', workerId);

});

//blur时进行校验

$workerIdInput.on('blur', function() {

  var workerId = $.trim($(this).val());

  //长度为0时,显示工号为空的错误信息

  if (!workerId.length) {

    showWorkerIdError(ERROR_WORKER_ID_IS_NULL);

    return false;

  }

  //若用户当前输入的数据和上次输入的数据一样,则不调用后台接口

  //假设用户输入123456,调用后台接口,返回结果为,不正确的工号

  //用户将输入内容进行更改后,仍然为123456,则校验程序不会访问网络,直接显示错误信息

  if (workerId == $(this).data('before')) {

    if (!isWorkerIdCorrect) {

      showWorkerIdError(ERROR_WORKER_ID_IS_NOT_CORRECT);

    }

    return false;

  }

  //调用后台接口,查询此员工id是否正确

  checkWorkerIdExists(workerId, function(data) {

    isWorkerIdCorrect = data.isWorkerIdExists;

    if (!isWorkerIdCorrect) {

      showWorkerIdError(ERROR_WORKER_ID_IS_NOT_CORRECT);

    }

  });

});

function checkWorkerIdExists(workerId, callback) {

  $.ajax({

    url: BASE_PATH + '/forgotPwd/checkWorkerIdExists.htm',

    data: {

      workerId: workerId

    },

    success: callback

  });

}

$workerIdForm.on('submit', function() {

  //只有服务器返回为true的时候,我们的表单才能提交

  if (!isWorkerIdCorrect) {

    $workerIdInput.focus();

    return false;

  }

});

上述代码写完,一个输入框的验证基本上搞定了。

我觉得还有影响用户体验的地方
还不支持回车操作,oh my god,回车也要能提交表单
若用户网速较慢,点击提交按钮,会没有任何反映,因为isWorkerIdCorrect为false,只有服务器校验成功才为true

下面是修改后的代码:

var BASE_PATH = '${rc.contextPath}';

var $workerIdInput = $('#workerIdInput');

var $workerIdError = $('#workerIdError');

//标识用户输入的工号是否正确

var isWorkerIdCorrect = false;

//标识后台校验工号是否已完成(true: 为校验中, false: 校验没开始或已结束)

var isWorkerIdLoading = false;

//标识用户是否提交了表单

var isSubmit = false;

var ERROR_WORKER_ID_IS_NULL = "员工工号不能为空";

var ERROR_WORKER_ID_IS_NOT_CORRECT = "请输入有效的员工工号";

//显示错误信息

function showWorkerIdError(errorMessage) {

  $workerIdError.html(errorMessage);

  $workerIdError.show();

}

//隐藏错误信息

$workerIdInput.on('keydown', function() {

  $workerIdError.hide();

});

//将上次输入的工号保存起来

$workerIdInput.on('focus', function() {

  var workerId = $.trim($(this).val());

  $(this).data('before', workerId);

});

//blur时进行校验

$workerIdInput.on('blur', function() {

  var workerId = $.trim($(this).val());

  //长度为0时,显示工号为空的错误信息

  if (!workerId.length) {

    showWorkerIdError(ERROR_WORKER_ID_IS_NULL);

    return false;

  }

  //若用户当前输入的数据和上次输入的数据一样,则不调用后台接口

  //假设用户输入123456,调用后台接口,返回结果为,不正确的工号

  //用户将输入内容进行更改后,仍然为123456,则校验程序不会访问网络,直接显示错误信息

  if (workerId == $(this).data('before')) {

    if (!isWorkerIdCorrect) {

      showWorkerIdError(ERROR_WORKER_ID_IS_NOT_CORRECT);

    }

    return false;

  }

  //调用后台接口,查询此员工id是否存在

  checkWorkerIdExists(workerId, function(data) {

    isWorkerIdCorrect = data.isWorkerIdExists;

    if (!isWorkerIdCorrect) {

      showWorkerIdError(ERROR_WORKER_ID_IS_NOT_CORRECT);

    }

  });

});

function checkWorkerIdExists(workerId, callback) {

  $.ajax({

    url: BASE_PATH + '/forgotPwd/checkWorkerIdExists.htm',

    data: {

      workerId: workerId

    },

    beforeSend: function() {

      //发送请求前,标识正在校验工号

      isWorkerIdLoading = true;

    },

    success: callback,

    complete: function() {

      //结束后,关闭标识

      isWorkerIdLoading = false;

      //在后台校验数据过程中,用户若提交了表单,则在此自动提交

      if (isSubmit) {

        $workerIdForm.submit();

      }

    }

  });

}

//回车提交表单

$workerIdInput.on('keypress', function(e) {

  if (e.which === 13) {

    $(this).blur();

    $workerIdForm.submit();

  }

});

$workerIdForm.on('submit', function() {

  //若正在后台校验工号,则标识用户提交了表单

  if (isWorkerIdLoading) {

    isSubmit = true;

    return false;

  }

  if (!isWorkerIdCorrect) {

    $workerIdInput.focus();

    return false;

  }

});

最终效果,图中2个输入框均为异步校验,但效果看起来和同步的一样。
图中使用了gprs网络模拟网速较慢的情况

效果图

javascript将异步校验表单改写为同步表单

Javascript 相关文章推荐
javascript removeChild 使用注意事项
Apr 11 Javascript
jQuery仿gmail实现fixed布局的方法
May 27 Javascript
jQuery Mobile操作HTML5的常用函数总结
May 17 Javascript
AngularJS通过ng-route实现基本的路由功能实例详解
Dec 13 Javascript
BootStrap3中模态对话框的使用
Jan 06 Javascript
jQuery排序插件tableSorter使用方法
Feb 10 Javascript
使用prop解决一个checkbox选中后再次选中失效的问题
Jul 05 Javascript
使用node打造自己的命令行工具方法教程
Mar 26 Javascript
使用ng-packagr打包Angular的方法示例
Sep 21 Javascript
axios使用拦截器统一处理所有的http请求的方法
Nov 02 Javascript
vue使用laydate时间插件的方法
Nov 14 Javascript
Postman如何实现参数化执行及断言处理
Jul 28 Javascript
JavaScript中实现sprintf、printf函数
Jan 27 #Javascript
javascript批量修改文件编码格式的方法
Jan 27 #Javascript
JavaScript中的包装对象介绍
Jan 27 #Javascript
浅谈JSON中stringify 函数、toJosn函数和parse函数
Jan 26 #Javascript
浅谈JavaScript Math和Number对象
Jan 26 #Javascript
js判断一个字符串是否包含一个子串的方法
Jan 26 #Javascript
javascript中Object使用详解
Jan 26 #Javascript
You might like
DC《小丑》11项提名领跑奥斯卡 Netflix成第92届奥斯卡提名最大赢家
2020/04/09 欧美动漫
PHP Class&Object -- PHP 自排序二叉树的深入解析
2013/06/25 PHP
yii分页组件用法实例分析
2015/12/28 PHP
php实现构建排除当前元素的乘积数组方法
2018/10/06 PHP
JS应用之禁止抓屏、复制、打印
2008/02/21 Javascript
js Array对象的扩展函数代码
2013/04/24 Javascript
javaScript对文字按照拼音排序实现代码
2013/12/27 Javascript
jquery淡化版banner异步图片文字效果切换图片特效
2014/04/08 Javascript
JS只能输入正整数的简单实例
2016/10/07 Javascript
jquery插入兄弟节点的操作方法
2016/12/07 Javascript
解决Angular.Js与Django标签冲突的方案
2016/12/20 Javascript
AngularJS 文件上传控件 ng-file-upload详解
2017/01/13 Javascript
Angular.js跨controller实现参数传递的两种方法
2017/02/20 Javascript
vue实现单选和多选功能
2017/08/11 Javascript
手把手教你用Node.js爬虫爬取网站数据的方法
2018/07/05 Javascript
vue-cli3.0使用及部分配置详解
2018/08/29 Javascript
vue2.0+vue-router构建一个简单的列表页的示例代码
2019/02/13 Javascript
解决微信小程序中转换时间格式IOS不兼容的问题
2019/02/15 Javascript
使用axios发送post请求,将JSON数据改为form类型的示例
2019/10/31 Javascript
使用vuex存储用户信息到localStorage的实例
2019/11/11 Javascript
JS严格模式原理与用法实例分析
2020/04/27 Javascript
js实现类选择器和name属性选择器的示例步骤
2021/02/07 Javascript
[01:49]一目了然!DOTA2DotA快捷操作对比第二弹
2014/05/16 DOTA
python自动截取需要区域,进行图像识别的方法
2018/05/17 Python
django+echart绘制曲线图的方法示例
2018/11/26 Python
通过Python编写一个简单登录功能过程解析
2019/09/04 Python
Python类继承和多态原理解析
2020/02/05 Python
python em算法的实现
2020/10/03 Python
python excel和yaml文件的读取封装
2021/01/12 Python
windows系统Tensorflow2.x简单安装记录(图文)
2021/01/18 Python
教职工代表大会主持词
2014/04/01 职场文书
北京申奥口号
2014/06/19 职场文书
党小组意见范文
2015/06/08 职场文书
python 实现定时任务的四种方式
2021/04/01 Python
springboot 多数据源配置不生效遇到的坑及解决
2021/11/17 Java/Android
vue 自定义的组件绑定点击事件
2022/04/21 Vue.js