手工编写一个验证码功能组件

0 写在前面

  校历第7周,又到了周末,总得来讲这周还算不错,有一些自己的时间去学习自己喜欢的东西。不过软工项目就要开始做了,还是要予以重视的。在我室友的软工项目里,用到了一个注册验证的验证码,我看了看他在网上找的实现方法,感觉效果不太好,所以我决定亲自动手帮他实现一个!

  在这个验证码功能的实现过程中,我主要练习了以下几个知识点:

  • canvas绘图功能

  • JQuery的简单用法

  • JS鼠标响应

  • 以及其他CSS的布局与调整等等

  感兴趣的朋友可以点击博客右上角的小猫咪进入我的github,或点击这里下载源代码。

1 实现效果与需求分析

1-1 初始效果

  需要随机生成验证码图片,设置刷新与提交按钮,隐藏错误提示信息。

  

1-2 正确性验证

  需要对用户输入与验证码内容进行匹配验证。

  

  若输入正确,则提示正确,若有与后端交互,则可以向后端发送验证成功信息。在这里我采用的实现为自动刷新验证码,如有需求可恨容易地进行替换。

  

  若输入错误,则需根据错误类型(如不匹配或输入为空等),进行相应的错误提示。

  

  

1-3 其他功能

  在用户重新输入鼠标聚焦于输入框时,需要自动隐藏上述错误提示信息。

  

  此外,还应实现用户点击刷新按钮即可更换验证码的功能。

2 实现细节

2-1 初始化验证码文档结构

  在HTML部分,我们的实现比较简单,将整体上划分为4个部分:输入框、错误提示、验证码画布以及提交按钮。

  这里面用到的DOM包括input、span、button和canvas

  这里canvas是今天练习中的重点。

  代码如下:

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <meta name="viewport" content="width=device-width, initial-scale=1.0">
 6     <meta http-equiv="X-UA-Compatible" content="ie=edge">
 7     <title>Verification Code</title>
 8     <link rel="stylesheet" href="demo.css">
 9 </head>
10 <body>
11     <div class="wrapper">
12         <div class="inputBox">
13             <input type="text" class="inp">
14             <span class="icon"></span>
15         </div>
16         <p class="errorText">Wrong verification code!<br>Please check and input again!</p>
17         <div class="box">
18             <canvas id="myCanvas" width="270" height="80"></canvas>
19             <input type="button" class="refresh">
20         </div>
21         <button class="submit">submit</button>
22     </div>
23 
24     <script src="jquery.js"></script>
25     <script src="demo.js"></script> 
26 </body>
27 </html>

2-2 初始化样式

  在样式的初始化中,还是练习到了基本的CSS布局操作。

  这里主要有两个需要复习的地方:

  • box-sizing:border-box; 这个属性用来调整盒模型为IE盒模型。IE与W3C盒模型的区别在于对width的定义,IE盒模型中width包含了content+padding+border。因此我们常用这个属性使得盒模型的宽度更容易定义与控制。

  • position:relative; 关于定位,我们为了让子元素能使用absolute相对于其最近的有定位的父元素进行定位。因此,我们可以为要进行绝对定位的子元素最近的父元素设置一个position:relative;使子元素能够相对其进行定位。

  外层样式如下:

 1 *{
 2     margin: 0;
 3     padding: 0;
 4 }
 5 .wrapper{
 6     margin: 50px auto;
 7     padding: 20px;
 8     width: 350px;
 9     border: 1px solid #ccc;
10     border-radius: 15px;
11     box-sizing: border-box;
12     position: relative;
13 }

  输入框样式如下:

  这里我们对默认的输入框通过增加border-radius圆角,和padding内边距来进行美化。此外还可以去除掉input默认的外边框outline:none;

 1 .inputBox{
 2     position: relative; /*absolute定位相对于有定位的最近的父元素*/
 3 }
 4 .inputBox .inp{
 5     display: inline-block;
 6     width: 270px;
 7     border: 1px solid #ccc;
 8     border-radius: 5px;
 9     box-sizing: border-box; /*调整为IE盒模型,将border与padding计算入width内*/
10     padding: 10px;
11     margin: 10px 0;
12     outline: none;
13 }
14 .inputBox .icon{
15     display: none;
16     /* display: inline-block; */
17     height: 32px;
18     width: 32px;
19     background: url(images/true.png);
20     background-size: 100%;
21     position: absolute;
22     top: 50%;
23     right: 0;
24     margin-top: -16px;
25 }

  错误提示信息如下:

  在初始时需要隐藏,且不占位,因此需要用display:none;而不能用visibility或opacity来进行设置。

1 .errorText{
2     display: none;
3     /* display: inline-block; */
4     color: red;
5     font-size: 14px;
6     margin-left: -10px;
7     text-align: center;
8     margin-bottom: 10px;
9 }

  画布和刷新按钮的设置如下:

 1 canvas{
 2     border: 1px solid #000;
 3     border-radius: 5px;
 4     background: url(images/bg.jpg);
 5     box-sizing: border-box;
 6 }
 7 .box{
 8     position: relative;
 9 }
10 .refresh{
11     width: 32px;
12     height: 32px;
13     background: url(images/update.png);
14     background-size: 100%;
15     border: 0;
16     border-radius: 5px;
17     position: absolute;
18     top: 50%;
19     margin-top: -16px;
20     right: 0;
21     outline: none;
22     cursor: pointer;
23 }

  最后是提交按钮的设计,让button变得更好看:

 1 .submit{
 2     color: #fff;
 3     padding: 10px 20px;
 4     border: 0;
 5     border-radius: 5px;
 6     background-color: #62b900;
 7     font-size: 16px;
 8     outline: none;
 9     cursor: pointer;
10     margin-top: 15px;
11 }

2-3 生成验证码

  到这里我们已经搭好了验证码组件的框架,现在就可以为它填充内容并绑定响应事件了!

  在生成验证码的阶段,我们需要用到一个数组去存储验证码的“仓库”,从这个“仓库”中随机取指定长度位数的验证码进行组合拼接,生成我们的验证码。

  这里有以下几点需要说明:

  • arr.push(val); 实现了想数组尾部压入新的值val

  • String.fromCharCode(i); 实现了int->char

  • window.onload = function(){}; 提供主函数入口init()

 1 var arr=[0,1,2,3,4,5,6,7,8,9]; //存放数和字符作为随机库
 2 var canvasStr , valueRight ; //生成的验证码序列字符串
 3 var VCLEN = 6; //验证码长度
 4 var myCanvas; //画布
 5 var ctx; //画笔
 6 
 7 function init(){
 8     for(var i = 65 ; i < 122 ; i ++){ //生成随机库
 9         if(i > 90 && i < 97){
10             continue;
11         }
12         arr.push(String.fromCharCode(i));//向随机库中压入字符
13     }
14     createCanvas(); //绘制验证码
15     bindEvent(); //绑定鼠标点击响应
16 }
17 
18 window.onload = function(){
19     init(); //主函数入口
20 }

2-4 验证码的绘制createCanvas()

  每次绘制前需要对验证码存储进行清空操作。

  在JS中对dom元素进行操作需要首先获取它,JQuery中获取dom元素的方式非常简单,$(selector)即可获取到。

  在canvas上绘图需要创建一个“画笔”对象ctx,它由getContext('2d')生成,表示在2d空间内进行绘制。

 1 function createCanvas(){
 2     var len = arr.length;
 3     canvasStr = ''; //每次绘制前必须清空验证码串
 4     valueRight = '';
 5     for(var i = 0 ; i < VCLEN ; i ++){ //生成验证码
 6         var text = arr[Math.floor(Math.random() * len)];
 7         canvasStr += (text + " "); //画布上的验证码之间有空格
 8         valueRight += text;
 9     }
10 
11     myCanvas = $('#myCanvas')[0]; //从html中获取Canvas元素
12     ctx = myCanvas.getContext('2d'); //创建二维画笔,方法返回一个用于在画布上绘图的环境
13 
14     drawLine(); //绘制干扰用线条
15     fillVerificationCode(); //绘制验证码字符
16 }

  画线函数:

 1 function drawLine(){
 2     ctx.beginPath(); //开始绘制
 3     ctx.clearRect(0,0,myCanvas.width,myCanvas.height); //清空画布区域,坐标点(x1,y1,x2,y2)
 4     ctx.lineWidth = 15; //规定宽度
 5     ctx.strokeStyle = '#ccc'; //规定线条颜色
 6     ctx.moveTo(Math.floor(Math.random()*30) , Math.floor(Math.random()*80)); //规定起点
 7     ctx.lineTo(250+Math.floor(Math.random()*20) , Math.floor(Math.random()*80)); //规定终点
 8     ctx.stroke(); //绘制
 9     ctx.globalCompositeOperation = 'lighter'; //源图像与目标图像叠加显示
10     ctx.closePath(); //结束绘制
11 }

  绘制验证码函数: 

 1 function fillVerificationCode(){
 2     //若要进行平移、放缩、旋转、错切、裁剪等操作,需再其前后增加save()和restore()。
 3     ctx.save();
 4     ctx.beginPath();
 5     var x = myCanvas.width / 2;
 6     ctx.textAlign = 'center';
 7     ctx.fillStyle = '#ddd';
 8     ctx.font = '46px Roboto Slab';
 9     ctx.setTransform(1 , -0.12 , 0.2 , 1 , 0 , 12); //将文字设置倾斜效果
10     ctx.fillText(canvasStr , x , 60); //参数:内容,开始点坐标x,y
11     ctx.restore();
12 }

2-5 对用户输入的验证与刷新

   好了,现在我们已经绘制成功了验证码,接下来就需要编写验证逻辑和增加鼠标响应了。

  大致思路就是为submit、refresh和input的聚焦绑定一个鼠标点击事件的监听,每当触发时就进行响应。

  如果点击了refresh,则调用一下上面编写过的createCanvas()重新生成一个验证码,并隐藏掉错误提示。

  如果是input的聚焦,则隐藏错误提示。

  如果点击了submit,则进行多步判断:是否为空、是否匹配,并根据判断结果做出具体响应。

  这里主要练习到了JQuery的以下几个要点:

  • val(): 取得输入的值,通常与input搭配使用

  • trim(): 可以过滤掉string前后的空白(包括空格和tab)

  • show(): 可以取消display:none的效果

  • html(): 相当于InnerHTML

  • css(): 可以编辑选中元素的CSS样式,注意属性值用' '来包含

  • add(): 添加一个新元素到JQuery对象

  • fadeOut(time): 淡出(消失)

 1 function bindEvent(){
 2     //为提交绑定鼠标点击事件
 3     $('.submit').on('click',function(){
 4         //获取输入
 5         var value = $('.inp').val().trim(); //trim()会去掉内容前后的空白
 6         //先判断是否输入为空
 7          if(value == '' || value == null || value == undefined){
 8              // show()可以取消display:none  html(text)可以改变html里的内容
 9              $('.errorText').show().html('Please input context.');
10              // css()可以修改选中元素的样式,用','分割,内容需要用''包含。
11              $('.icon').css({
12                  display: 'inline-block',
13                  backgroundImage: 'url("images/false.png")'
14              });
15          }
16          else{
17              // 判断是否与目标相一致
18              if(value == valueRight){
19                  $('.icon').css({
20                      display: 'inline-block',
21                      backgroundImage: 'url("images/true.png")'
22                  });
23                  createCanvas(); //可以用向后端反馈验证成功信息代替之
24              }
25              else{
26                 $('.errorText').show().html('Wrong verification code!<br>Please check and input again!.');
27                 $('.icon').css({
28                     display: 'inline-block',
29                     backgroundImage: 'url("images/false.png")'
30                 });
31              }
32          }
33     })
34     //为刷新按钮添加鼠标点击事件
35     $('.refresh').on('click',function(){
36         createCanvas();
37         //add()用于添加一个元素到jQuery对象。fadeOut()淡出(逐渐消失)
38         $('.errorText').add('.icon').fadeOut(100);
39     });
40     //错误提示后鼠标再次聚焦消除错误提示
41     $('.inp').focus(function(){
42         $('.errorText').add('.icon').fadeOut(100);
43     });
44 }

  

猜你喜欢

转载自www.cnblogs.com/chrischen98/p/10695138.html