原生JS 表单提交验证器
转载:http://www.cnblogs.com/sicd/p/4613628.html
一、前言
最近在开发一个新项目,需要做登陆等一系列的表单提交页面。在经过“缜密”的讨论后,我们决定 不用外部流行的框架,如bootstrap,由于我负责的模块
仅仅是其中的一部分,因此少数服从多数,无奈只能抛弃bootstrap等提供的布局,样式以及验证等一些列如此方便的组件,(他们拒绝使用的原因也令人发省)。
那么问题就来了。
二、设计理念
我们都知道,在抛开外部框架,仅仅用JS+css+html 去开发一个页面,是很复杂的,尤其是在没有美工,前台的情况下。其实bootstrap 在一定程度上 为公司节省了 美工 前台的开支...
废话少说,1天搞定了页面之后,开始为表单添加JS验证。用原生JS写验证是一件很吃力的事情,就算把各种验证方式,正则表达式,为空判断,长度判断,复杂各类字符组合判断等,集中到一个文件当中,依然可能无法排除每个页面中各种的条件语句,万一一个表单 N个input呢?
而jquery validate组件 等 是怎样实现的呢,其实现实中表示,只要会用就行了 不用了解其工作原理。就像你只要会开汽车 就足够了,不用去了解车是怎么实现的,那么当你有一天会开飞机,那么你就登上了人生的“巅峰”。
三、自定义验证器
废话不多说 直接上代码
1 /** 2 * Created by sicd 2015-5-29. 3 */ 4 $(function(){ 5 }); 6 7 var suc_img='<i class="error-img"></i>'; 8 var err_tag='<span class="error-msg" id="error-msg" style="display: block;"></span>'; 9 10 11 12 function isIP(strIP) { 13 if (isNull(strIP)) return false; 14 var re=/^(\d+)\.(\d+)\.(\d+)\.(\d+)$/g //匹配IP地址的正则表达式 15 if(re.test(strIP)) 16 { 17 if( RegExp.$1 <256 && RegExp.$2<256 && RegExp.$3<256 && RegExp.$4<256) return true; 18 } 19 return false; 20 } 21 22 /* 23 用途:检查输入字符串是否为空或者全部都是空格 24 输入:str 25 返回: 26 如果全是空返回true,否则返回false 27 */ 28 function isNull( str ){ 29 if ( str == "" ) return true; 30 var regu = "^[ ]+$"; 31 var re = new RegExp(regu); 32 return re.test(str); 33 } 34 35 36 /* 37 用途:检查输入对象的值是否符合整数格式 38 输入:str 输入的字符串 39 返回:如果通过验证返回true,否则返回false 40 41 */ 42 function isInteger( str ){ 43 var regu = /^[-]{0,1}[0-9]{1,}$/; 44 return regu.test(str); 45 } 46 47 /* 48 用途:检查输入手机号码是否正确 49 输入: 50 s:字符串 51 返回: 52 如果通过验证返回true,否则返回false 53 54 */ 55 function checkMobile( s ){ 56 var regu =/^[1][3][0-9]{9}$/; 57 var re = new RegExp(regu); 58 if (re.test(s)) { 59 return true; 60 }else{ 61 return false; 62 } 63 } 64 65 66 /* 67 用途:检查输入字符串是否符合正整数格式 68 输入: 69 s:字符串 70 返回: 71 如果通过验证返回true,否则返回false 72 73 */ 74 function isNumber( s ){ 75 var regu = "^[0-9]+$"; 76 var re = new RegExp(regu); 77 if (s.search(re) != -1) { 78 return true; 79 } else { 80 return false; 81 } 82 } 83 84 /* 85 用途:检查输入字符串是否是带小数的数字格式,可以是负数 86 输入: 87 s:字符串 88 返回: 89 如果通过验证返回true,否则返回false 90 91 */ 92 function isDecimal( str ){ 93 if(isInteger(str)) return true; 94 var re = /^[-]{0,1}(\d+)[\.]+(\d+)$/; 95 if (re.test(str)) { 96 if(RegExp.$1==0&&RegExp.$2==0) return false; 97 return true; 98 } else { 99 return false; 100 } 101 } 102 103 /* 104 用途:检查输入对象的值是否符合端口号格式 105 输入:str 输入的字符串 106 返回:如果通过验证返回true,否则返回false 107 108 */ 109 function isPort( str ){ 110 return (isNumber(str) && str<65536); 111 } 112 113 /* 114 用途:检查输入对象的值是否符合E-Mail格式 115 输入:str 输入的字符串 116 返回:如果通过验证返回true,否则返回false 117 118 */ 119 function isEmail( str ){ 120 var myReg = /^[-_A-Za-z0-9]+@([_A-Za-z0-9]+\.)+[A-Za-z0-9]{2,3}$/; 121 if(myReg.test(str)) return true; 122 return false; 123 } 124 125 /* 126 用途:检查输入字符串是否符合金额格式 127 格式定义为带小数的正数,小数点后最多三位 128 输入: 129 s:字符串 130 返回: 131 如果通过验证返回true,否则返回false 132 133 */ 134 function isMoney( s ){ 135 var regu = "^[0-9]+[\.][0-9]{0,3}$"; 136 var re = new RegExp(regu); 137 if (re.test(s)) { 138 return true; 139 } else { 140 return false; 141 } 142 } 143 /* 144 用途:检查输入字符串是否只由英文字母和数字和下划线组成 145 输入: 146 s:字符串 147 返回: 148 如果通过验证返回true,否则返回false 149 150 */ 151 function isNumberOr_Letter( s ){//判断是否是数字或字母 152 153 var regu = "^[0-9a-zA-Z\_]+$"; 154 var re = new RegExp(regu); 155 if (re.test(s)) { 156 return true; 157 }else{ 158 return false; 159 } 160 } 161 /* 162 用途:检查输入字符串是否只由英文字母和数字组成 163 输入: 164 s:字符串 165 返回: 166 如果通过验证返回true,否则返回false 167 168 */ 169 function isNumberOrLetter( s ){//判断是否是数字或字母 170 171 var regu = "^[0-9a-zA-Z]+$"; 172 var re = new RegExp(regu); 173 if (re.test(s)) { 174 return true; 175 }else{ 176 return false; 177 } 178 } 179 /* 180 用途:检查输入字符串是否只由汉字、字母、数字组成 181 输入: 182 value:字符串 183 返回: 184 如果通过验证返回true,否则返回false 185 186 */ 187 function isChinaOrNumbOrLett( s ){//判断是否是汉字、字母、数字组成 188 189 var regu = "^[0-9a-zA-Z\u4e00-\u9fa5]+$"; 190 var re = new RegExp(regu); 191 if (re.test(s)) { 192 return true; 193 }else{ 194 return false; 195 } 196 } 197 198 /* 199 用途:判断是否是日期 200 输入:date:日期;fmt:日期格式 201 返回:如果通过验证返回true,否则返回false 202 */ 203 function isDate( date, fmt ) { 204 if (fmt==null) fmt="yyyyMMdd"; 205 var yIndex = fmt.indexOf("yyyy"); 206 if(yIndex==-1) return false; 207 var year = date.substring(yIndex,yIndex+4); 208 var mIndex = fmt.indexOf("MM"); 209 if(mIndex==-1) return false; 210 var month = date.substring(mIndex,mIndex+2); 211 var dIndex = fmt.indexOf("dd"); 212 if(dIndex==-1) return false; 213 var day = date.substring(dIndex,dIndex+2); 214 if(!isNumber(year)||year>"2100" || year< "1900") return false; 215 if(!isNumber(month)||month>"12" || month< "01") return false; 216 if(day>getMaxDay(year,month) || day< "01") return false; 217 return true; 218 } 219 220 function getMaxDay(year,month) { 221 if(month==4||month==6||month==9||month==11) 222 return "30"; 223 if(month==2) 224 if(year%4==0&&year%100!=0 || year%400==0) 225 return "29"; 226 else 227 return "28"; 228 return "31"; 229 } 230 231 /* 232 用途:字符1是否以字符串2结束 233 输入:str1:字符串;str2:被包含的字符串 234 返回:如果通过验证返回true,否则返回false 235 236 */ 237 function isLastMatch(str1,str2) 238 { 239 var index = str1.lastIndexOf(str2); 240 if(str1.length==index+str2.length) return true; 241 return false; 242 } 243 244 245 /* 246 用途:字符1是否以字符串2开始 247 输入:str1:字符串;str2:被包含的字符串 248 返回:如果通过验证返回true,否则返回false 249 250 */ 251 function isFirstMatch(str1,str2) 252 { 253 var index = str1.indexOf(str2); 254 if(index==0) return true; 255 return false; 256 } 257 258 /* 259 用途:字符1是包含字符串2 260 输入:str1:字符串;str2:被包含的字符串 261 返回:如果通过验证返回true,否则返回false 262 263 */ 264 function isMatch(str1,str2) 265 { 266 var index = str1.indexOf(str2); 267 if(index==-1) return false; 268 return true; 269 } 270 271 272 /* 273 用途:检查输入的起止日期是否正确,规则为两个日期的格式正确, 274 且结束如期>=起始日期 275 输入: 276 startDate:起始日期,字符串 277 endDate:结束如期,字符串 278 返回: 279 如果通过验证返回true,否则返回false 280 281 */ 282 function checkTwoDate( startDate,endDate ) { 283 if( !isDate(startDate) ) { 284 alert("起始日期不正确!"); 285 return false; 286 } else if( !isDate(endDate) ) { 287 alert("终止日期不正确!"); 288 return false; 289 } else if( startDate > endDate ) { 290 alert("起始日期不能大于终止日期!"); 291 return false; 292 } 293 return true; 294 } 295 296 /* 297 用途:检查输入的Email信箱格式是否正确 298 输入: 299 strEmail:字符串 300 返回: 301 如果通过验证返回true,否则返回false 302 303 */ 304 function checkEmail(strEmail) { 305 //var emailReg = /^[_a-z0-9]+@([_a-z0-9]+\.)+[a-z0-9]{2,3}$/; 306 var emailReg = /^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$/; 307 if( emailReg.test(strEmail) ){ 308 return true; 309 }else{ 310 alert("您输入的Email地址格式不正确!"); 311 return false; 312 } 313 } 314 315 /* 316 用途:检查输入的电话号码格式是否正确 317 输入: 318 strPhone:字符串 319 返回: 320 如果通过验证返回true,否则返回false 321 322 */ 323 function checkPhone( strPhone ) { 324 var phoneRegWithArea = /^[0][1-9]{2,3}-[0-9]{5,10}$/; 325 var phoneRegNoArea = /^[1-9]{1}[0-9]{5,8}$/; 326 var prompt = "您输入的电话号码不正确!" 327 if( strPhone.length > 9 ) { 328 if( phoneRegWithArea.test(strPhone) ){ 329 return true; 330 }else{ 331 alert( prompt ); 332 return false; 333 } 334 }else{ 335 if( phoneRegNoArea.test( strPhone ) ){ 336 return true; 337 }else{ 338 alert( prompt ); 339 return false; 340 } 341 342 343 } 344 } 345 346 347 /* 348 用途:检查复选框被选中的数目 349 输入: 350 checkboxID:字符串 351 返回: 352 返回该复选框中被选中的数目 353 354 */ 355 356 function checkSelect( checkboxID ) { 357 var check = 0; 358 var i=0; 359 if( document.all(checkboxID).length > 0 ) { 360 for( i=0; i<document.all(checkboxID).length; i++ ) { 361 if( document.all(checkboxID).item( i ).checked ) { 362 check += 1; 363 } 364 } 365 }else{ 366 if( document.all(checkboxID).checked ) 367 check = 1; 368 } 369 return check; 370 } 371 372 /* 373 * 374 * 检查是否是64的倍数 375 */ 376 function Is64Multi(num){ 377 if(num % 64 == 0){ 378 return true; 379 }else{ 380 return false; 381 } 382 } 383 384 function getTotalBytes(varField) { 385 if(varField == null) 386 return -1; 387 388 var totalCount = 0; 389 for (i = 0; i< varField.value.length; i++) { 390 if (varField.value.charCodeAt(i) > 127) 391 totalCount += 2; 392 else 393 totalCount++ ; 394 } 395 return totalCount; 396 } 397 398 function getFirstSelectedValue( checkboxID ){ 399 var value = null; 400 var i=0; 401 if( document.all(checkboxID).length > 0 ){ 402 for( i=0; i<document.all(checkboxID).length; i++ ){ 403 if( document.all(checkboxID).item( i ).checked ){ 404 value = document.all(checkboxID).item(i).value; 405 break; 406 } 407 } 408 } else { 409 if( document.all(checkboxID).checked ) 410 value = document.all(checkboxID).value; 411 } 412 return value; 413 } 414 415 416 function getFirstSelectedIndex( checkboxID ){ 417 var value = -2; 418 var i=0; 419 if( document.all(checkboxID).length > 0 ){ 420 for( i=0; i<document.all(checkboxID).length; i++ ) { 421 if( document.all(checkboxID).item( i ).checked ) { 422 value = i; 423 break; 424 } 425 } 426 } else { 427 if( document.all(checkboxID).checked ) 428 value = -1; 429 } 430 return value; 431 } 432 433 function selectAll( checkboxID,status ){ 434 435 if( document.all(checkboxID) == null) 436 return; 437 438 if( document.all(checkboxID).length > 0 ){ 439 for( i=0; i<document.all(checkboxID).length; i++ ){ 440 441 document.all(checkboxID).item( i ).checked = status; 442 } 443 } else { 444 document.all(checkboxID).checked = status; 445 } 446 } 447 448 function selectInverse( checkboxID ) { 449 if( document.all(checkboxID) == null) 450 return; 451 452 if( document.all(checkboxID).length > 0 ) { 453 for( i=0; i<document.all(checkboxID).length; i++ ) { 454 document.all(checkboxID).item( i ).checked = !document.all(checkboxID).item( i ).checked; 455 } 456 } else { 457 document.all(checkboxID).checked = !document.all(checkboxID).checked; 458 } 459 } 460 461 function checkDate( value ) { 462 if(value=='') return true; 463 if(value.length!=8 || !isNumber(value)) return false; 464 var year = value.substring(0,4); 465 if(year>"2100" || year< "1900") 466 return false; 467 468 var month = value.substring(4,6); 469 if(month>"12" || month< "01") return false; 470 471 var day = value.substring(6,8); 472 if(day>getMaxDay(year,month) || day< "01") return false; 473 474 return true; 475 } 476 477 /* 478 用途:检查输入的起止日期是否正确,规则为两个日期的格式正确或都为空 479 且结束日期>=起始日期 480 输入: 481 startDate:起始日期,字符串 482 endDate: 结束日期,字符串 483 返回: 484 如果通过验证返回true,否则返回false 485 486 */ 487 function checkPeriod( startDate,endDate ) { 488 if( !checkDate(startDate) ) { 489 alert("起始日期不正确!"); 490 return false; 491 } else if( !checkDate(endDate) ) { 492 alert("终止日期不正确!"); 493 return false; 494 } else if( startDate > endDate ) { 495 alert("起始日期不能大于终止日期!"); 496 return false; 497 } 498 return true; 499 } 500 501 /* 502 用途:检查证券代码是否正确 503 输入: 504 secCode:证券代码 505 返回: 506 如果通过验证返回true,否则返回false 507 508 */ 509 function checkSecCode( secCode ) { 510 if( secCode.length !=6 ){ 511 alert("证券代码长度应该为6位"); 512 return false; 513 } 514 515 if(!isNumber( secCode ) ){ 516 alert("证券代码只能包含数字"); 517 518 519 return false; 520 } 521 return true; 522 } 523 524 /**************************************************** 525 function:cTrim(sInputString,iType) 526 description:字符串去空格的函数 527 parameters:iType:1=去掉字符串左边的空格 528 529 2=去掉字符串左边的空格 530 0=去掉字符串左边和右边的空格 531 return value:去掉空格的字符串 532 ****************************************************/ 533 function cTrim(sInputString,iType) { 534 var sTmpStr = ' '; 535 var i = -1; 536 537 if (iType == 0 || iType == 1) { 538 while (sTmpStr == ' ') { 539 ++i; 540 sTmpStr = sInputString.substr(i, 1); 541 } 542 sInputString = sInputString.substring(i); 543 } 544 545 if (iType == 0 || iType == 2) { 546 sTmpStr = ' '; 547 i = sInputString.length; 548 while (sTmpStr == ' ') { 549 --i; 550 sTmpStr = sInputString.substr(i, 1); 551 } 552 sInputString = sInputString.substring(0, i + 1); 553 } 554 return sInputString; 555 } 556 function checkLength (str, lessLen, moreLen) { 557 var strLen = this.length(str); 558 if (lessLen != "") { 559 if (strLen < lessLen) 560 return false; 561 } 562 } 563 564 /*描述对字段验证的类*/ 565 function Field(params){ 566 this.field_id=params.fid; //要验证的字段的ID 567 this.validators=params.val; //验证器对象数组 568 this.on_suc=params.suc; //当验证成功的时候执行的事件 569 this.on_error=params.err; //当验证失败的时候执行的事件 570 this.checked=false; //是否通过验证 571 } 572 573 /*扩展这个类,加入validate方法*/ 574 Field.prototype.validate=function(){ 575 //循环每一个验证器 576 for ( var item=0;item<this.validators.length;item++ ){ 577 /*for(item in this.valid{ators)*/ 578 //给验证器附加验证成功和验证失败的回调事件 579 this.set_callback(this.validators[item]); 580 //执行验证器上的Validate方法,验证是否符合规则 581 if(this.validators[item]){ 582 if(!this.validators[item].validate(this.data())){ 583 break; //一旦任意一个验证器失败就停止 584 } 585 } 586 } 587 }; 588 //获取字段值的方法 589 Field.prototype.data=function(){ 590 return document.getElementById(this.field_id).value; 591 }; 592 593 //获取该字段的对象 594 Field.prototype.obj=function(){ 595 return document.getElementById(this.field_id); 596 } 597 /*设置验证器回调函数的方法set_callback如下:*/ 598 Field.prototype.set_callback=function(val){ 599 var self=this; //换一个名字来存储this,不然函数的闭包中会覆盖这个名字 600 if(val){ 601 602 val.on_suc=function(){ //验证成功执行的方法 603 self.checked=true; //将字段设置为验证成功 604 /*self.on_suc(val.tips); //执行验证成功的事件*/ 605 //不执行回调 606 $(self.obj()).attr('class','validate-suc'); 607 $(self.obj()).nextAll('.error-img').show(); 608 $(self.obj()).nextAll('.error-msg').hide().text(val.tips); 609 610 }; 611 val.on_error=function(){ //验证失败的时候执行的方法 612 self.checked=false; //字段设置为验证失败 613 /*self.on_error(val.tips);//执行验证失败的事件*/ 614 //不执行回调 615 $(self.obj()).attr('class','validate-err'); 616 $(self.obj()).nextAll('.error-img').hide(); 617 $('.error-msg').hide(); 618 $(self.obj()).nextAll('.error-msg').css('display','inline').text(val.tips); 619 } 620 } 621 }; 622 /*验证器*/ 623 624 //非空验证 625 function Null_val(tip){ 626 this.tips = tip; 627 this.on_suc=null; 628 this.on_error=null; 629 } 630 Null_val.prototype.validate=function(fd){ 631 if(isNull(fd)){ 632 this.on_error(); 633 return false; 634 } 635 this.on_suc(); 636 return true; 637 } 638 639 //长度验证 640 function Len_val(min_l,max_l,tip){ 641 this.min_v=min_l; 642 this.max_v=max_l; 643 this.tips=tip; 644 this.on_suc=null; 645 this.on_error=null; 646 } 647 Len_val.prototype.validate=function(fd){ 648 if(fd.length<this.min_v||fd.length>this.max_v){ 649 this.on_error(); 650 return false; 651 } 652 this.on_suc(); 653 return true; 654 } 655 656 //正整数数字验证 657 function PosiInteg_val(tip){ 658 this.tips=tip; 659 this.on_suc=null; 660 this.on_error=null; 661 } 662 PosiInteg_val.prototype.validate = function(fd){ 663 if(!isNumber(fd)){ 664 this.on_error(); 665 return false; 666 } 667 this.on_suc(); 668 return true; 669 } 670 671 //是否是64的倍数 672 function Is64Multiple(tip){ 673 this.tips=tip; 674 this.on_suc=null; 675 this.on_error=null; 676 } 677 Is64Multiple.prototype.validate = function(fd){ 678 if(!Is64Multi(fd)){ 679 this.on_error(); 680 return false; 681 } 682 this.on_suc(); 683 return true; 684 } 685 686 //select是否选择验证 687 Select_isSelected.prototype.validate=function(fd){ 688 if(fd == -1){ 689 this.on_error(); 690 return false; 691 } 692 this.on_suc(); 693 return true; 694 } 695 function Select_isSelected(tip){ 696 this.tips=tip; 697 this.on_suc=null; 698 this.on_error=null; 699 } 700 701 //正则表达式验证器 702 function Exp_val(expresion,tip){ 703 this.exps=expresion; 704 this.tips=tip; 705 this.on_suc=null; 706 this.on_error=null; 707 } 708 Exp_val.prototype.validate=function(fd){ 709 if(!fd){ 710 this.on_suc(); 711 return true; 712 } 713 if(this.exps.test(fd)){ 714 this.on_suc(); 715 return true; 716 }else{ 717 this.on_error(); 718 return false; 719 } 720 } 721 //远程验证器 722 function Remote_val(url,tip){ 723 this.p_url=url; 724 this.tips=tip; 725 this.on_suc=null; 726 this.on_error=null; 727 } 728 Remote_val.prototype.validate=function(fd){ 729 var self=this; 730 $.post(this.p_url,{f:fd}, 731 function(data){ 732 if(data.rs){ 733 self.on_suc(); 734 return; 735 }else{ 736 self.on_error(); 737 } 738 },"json" 739 ); 740 return false; 741 } 742 //自定义函数验证器 743 function Man_val(tip,func){ 744 this.tips=tip; 745 this.val_func=func; 746 this.on_suc=null; 747 this.on_error=null; 748 } 749 Man_val.prototype.validate=function(fd){ 750 if(this.val_func(fd)){ 751 this.on_suc(); 752 }else{ 753 this.on_error(); 754 } 755 } 756 757 function FieldForm(items){ 758 this.f_item=items; //把字段验证对象数组复制给属性 759 for(idx=0;idx<this.f_item.length;idx++){ //循环数组 760 var fc=this.get_check(this.f_item[idx]); //获取封装后的回调事件 761 $("#"+this.f_item[idx].field_id).change(fc); //绑定到控件上 762 } 763 }; 764 //绑定验证事件的处理器,为了避开循环对闭包的影响 765 FieldForm.prototype.get_check=function(v){ 766 return function(){ //返回包装了调用validate方法的事件 767 v.validate(); 768 } 769 } 770 /*绑定按钮click*/ 771 FieldForm.prototype.set_submit=function(bid,bind){ 772 var self=this; 773 $("#"+bid).click( 774 function(){ 775 if(self.validate()){ 776 bind(); 777 } 778 } 779 ); 780 } 781 /*这里提到了一个FieldForm的validate方法*/ 782 FieldForm.prototype.validate=function(){ 783 for(idx in this.f_item){ //循环每一个验证器 784 this.f_item[idx].validate(); //再检测一遍 785 if(!this.f_item[idx].checked){ 786 return false; //如果错误就返回失败,阻止提交 787 } 788 } 789 return true; //一个都没错就返回成功执行提交 790 } 791 792 //绑定输入框foucs事件 检测 793 $(function(){ 794 $('.theme-normal input').bind('click', function() { 795 if($(this).hasClass('validate-err')){ 796 $('.error-msg').hide(); 797 $(this).nextAll('.error-msg').css('display','inline'); 798 799 } 800 }); 801 });
原理就不多说了,或多或少都有注释,结构就是很简单,最上面一部分是验证方法集合,本人偷懒 直接写在一个文件里,中间部分就是验证器,关于事件触发,回调,定义等,
稍微花点时间就能够看懂。当然 本验证器 还有很多优化的地方,可以通过调整,改变成符合自己的专用验证器。
下面是调用,或者说是赋予标签 验证器:
var form; $(function() { //表单验证 var uf = new FieldForm([ new Field({fid : "captcha",val : [ new Null_val("验证码为必填项,请输入")]}), new Field({fid : "username",val : [ new Null_val("用户名为必填项,请输入"),new Len_val(1,8,"用户名长度不能超过8位,请重新输入!")]}), new Field({fid : "password",val : [ new Null_val("密码为必填项,请输入"),new Len_val(1,32,"密码长度不能超过32位,请重新输入!")]}) ]); uf.set_submit("subBtn", function(form) { $('#subBtn').parents('form').submit(); }); });
效果
其中样式 是我自己写的,当input(包括下拉框) 值 发生变化 则进行验证(可以调整验证器,改变触发形式),提交触发验证,input获得焦点时
如果之前验证不通过,则弹出提示框。
四、总结
很简单,一下午就能看懂 并且调整自如,由于本人懒,没有展示CSS相关的代码文件,如有兴趣,可以吧这些东西提取出来或者做整合
做成组件,做成像日期控件那样的,方便移植和运用。
本文来自博客园,作者:兴想事成,转载请注明原文链接:https://www.cnblogs.com/mjxxsc/p/4613695.html