【javascript】表单提交前多个异步校验

1.问题

每个异步校验完成时间不确定,js代码无法及时根据异步校验结果判断是否该提交表单.

2.解法方式

2.1 使用同步
  • 同步会等每个请求响应成功才会执行后面的js代码
  • 代码简单,效果好
  • 同步ajax会锁死页面,用户体验不好,严重的浏览器还会崩溃
$.ajax({
		async:false,     //同步		
});
2.2 使用计数器
  • 计数器用于记录异步校验的成功数,只有计数与需要异步校验数量一致才提交表单
  • 快速多次点击提交表单按钮可能导致计数出错
  • 不推荐使用
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
	<form name="form" method="post" action="https://www.baidu.com">
		<!-- 此处省略表单元素标签 -->
		
		<!-- 使用普通按钮代替提交按钮,避免事件触发多次调用checkForm() -->
		<input type="button" value="提交" id="btn_submit" onclick="checkForm()"/>
	</form>
</body>
<script> 
	
	//计数器
	var count=0;

    
    //表单提交前的数据校验
    function checkForm(){
    	/*此处省略校验其他普通数据*/
    	
    	//重置计数器
    	count=0;
    	
    	//调用各个异步校验
    	f1(true);
    	f2(true);
    	f3(true);
    	f4(true);
    }
    
    //提交表单
    function submitForm(){
    	if(count==4){
    		document.form.submit();
    	}
    }
    
    var flag4=false;
    
    //第一个异步校验
    //isSubmit是否表单提交前的校验
    function f1(isSubmit){
    	//模拟异步请求到服务器端,延时1秒
    	setTimeout(function(){   		
   			if(isSubmit){
   				//每个异步校验成功计算器+1,并且判断判断计算器是否满足条件提交表单
   				count++;
   				submitForm()
   			}   		
    	},1000);
    }
    
    //第二个异步校验
    function f2(isSubmit){
    	//模拟异步请求到服务器端,延时2秒
    	setTimeout(function(){   		
   			if(isSubmit){
   				count++;
   				submitForm()
   			}   		
    	},2000);
    }
    
    //第三个异步校验
    function f3(isSubmit){
    	//模拟异步请求到服务器端,延时3秒
    	setTimeout(function(){   		
   			if(isSubmit){
   				count++;
   				submitForm()
   			}   		
    	},3000);
    }
    
    //第四个异步校验
    function f4(isSubmit){   
   		//模拟异步请求到服务器端,延时4秒
    	setTimeout(function(){   		
   			if(isSubmit){
   				count++;
   				submitForm()
   			}   		
    	},4000);
    
    }
</script>
</html>

2.3 使用标志
  • 使用多个变量标志每个异步校验的结果,只有每个标志成功才提交表单
  • 标志变量多,但快速多次点击提交表单按钮不会判断错误
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
	<form name="form" method="post" action="https://www.baidu.com">
		<!-- 此处省略表单元素标签 -->
		
		<!-- 使用普通按钮代替提交按钮,避免事件触发多次调用checkForm() -->
		<input type="button" value="提交" id="btn_submit" onclick="checkForm()"/>
	</form>
</body>
<script> 
	
	//标志变量
	var flag1=false;
	var flag2=false;
	var flag3=false;
	var flag4=false;

    
    //表单提交前的数据校验
    function checkForm(){
    	/*此处省略校验其他普通数据*/
    	
    	//重置标志
    	var flag1=false;
		var flag2=false;
		var flag3=false;
		var flag4=false;
    	
    	//调用各个异步校验
    	f1(true);
    	f2(true);
    	f3(true);
    	f4(true);
    }
    
    //提交表单
    function submitForm(){
    	if(flag1&&flag2&&flag3&&flag4){
    		document.form.submit();
    	}
    }
    
    
    
    //第一个异步校验
    //isSubmit是否表单提交前的校验
    function f1(isSubmit){
    	//模拟异步请求到服务器端,延时1秒
    	setTimeout(function(){   		
   			if(isSubmit){
   				//校验成功把相应的标志设为true,每次校验成功都需要判断所有标志是否能满足提交表单
   				flag1=true;
   				submitForm()
   			}   		
    	},1000);
    }
    
    //第二个异步校验
    function f2(isSubmit){
    	//模拟异步请求到服务器端,延时2秒
    	setTimeout(function(){   		
   			if(isSubmit){
   				flag2=true;
   				submitForm()
   			}   		
    	},2000);
    }
    
    //第三个异步校验
    function f3(isSubmit){
    	//模拟异步请求到服务器端,延时3秒
    	setTimeout(function(){   		
   			if(isSubmit){
   				flag3=true;
   				submitForm()
   			}   		
    	},3000);
    }
    
   
    //第四个异步校验
    function f4(isSubmit){       	
   		//模拟异步请求到服务器端,延时4秒
    	setTimeout(function(){   		
   			if(isSubmit){
   				flag4=true;
   				submitForm()
   			}   		
    	},4000); 
    }
</script>
</html>
2.4使用位或
  • 位或:两个整数的对应二进制位,如果有一个为1,则结果为1,否则,结果为0
  • 二进制位所有位只有一个1的数:1,2,4,8,16,32…等等,所以这些数进行位或相应的位变成1,算数结果等同于求和(可以达到2.2的计数器效果)
  • 1,2,4,8,16,32…等数的每个位的1都是唯一的,所以必须每个数都被位或了才能使最终结果的每个位都是1,这些数多次被位或结果是不变的,所以就可以达到2.3的标志效果
  • 该方式不够直观,当代码位置比较乱时可能会漏掉或计算错误
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
	<form name="form" method="post" action="https://www.baidu.com">
		<!-- 此处省略表单元素标签 -->
		
		<!-- 使用普通按钮代替提交按钮,避免事件触发多次调用checkForm() -->
		<input type="button" value="提交" id="btn_submit" onclick="checkForm()"/>
	</form>
</body>
<script> 
	
	//位或结果
	var result=0;

    
    //表单提交前的数据校验
    function checkForm(){
    	/*此处省略校验其他普通数据*/
    	
    	//重置位或结果
    	result=0
    	
    	//调用各个异步校验
    	f1(true);
    	f2(true);
    	f3(true);
    	f4(true);
    }
    
    //提交表单
    function submitForm(){
    	//  1|2|4|8=15
    	if(result==15){
    		document.form.submit();
    	}
    }
    
    
    
    //第一个异步校验
    //isSubmit是否表单提交前的校验
    function f1(isSubmit){
    	//模拟异步请求到服务器端,延时1秒
    	setTimeout(function(){   		
   			if(isSubmit){
   				//校验成功位或相应数字(1,2,4,8),每次校验成功都需要判断是否能满足提交表单
   				result=result|1;
   				submitForm()
   			}   		
    	},1000);
    }
    
    //第二个异步校验
    function f2(isSubmit){
    	//模拟异步请求到服务器端,延时2秒
    	setTimeout(function(){   		
   			if(isSubmit){
   				result=result|2;
   				submitForm()
   			}   		
    	},2000);
    }
    
    //第三个异步校验
    function f3(isSubmit){
    	//模拟异步请求到服务器端,延时3秒
    	setTimeout(function(){   		
   			if(isSubmit){
   				result=result|4;
   				submitForm()
   			}   		
    	},3000);
    }
    
  
   
    //第四个异步校验
    function f4(isSubmit){        	
   		//模拟异步请求到服务器端,延时4秒
    	setTimeout(function(){   		
   			if(isSubmit){
   				result=result|8;
   				submitForm()
   			}   		
    	},4000);    	
    }
</script>
</html>
2.5 使用表单验证插件或者自己封装
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值