原生js實(shí)現(xiàn)驗(yàn)證碼功能(復(fù)制代碼直接用)

HTML代碼:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>圖形驗(yàn)證碼</title>
    </head>
    <body>
        <div id="v_container" style="width: 200px;height: 50px;"></div>
        <input type="text" id="code_input" value="" placeholder="請輸入驗(yàn)證碼"/><button id="my_button">驗(yàn)證</button>
    </body>
    <script src="./gVerify.js"></script>
    <script>
        var verifyCode = new GVerify("v_container");
 
        document.getElementById("my_button").onclick = function(){
            var res = verifyCode.validate(document.getElementById("code_input").value);
            if(res){
                alert("驗(yàn)證正確");
            }else{
                alert("驗(yàn)證碼錯誤");
            }
        }
    </script>
</html>

gVerify.js代碼:

!(function(window, document) {
    function GVerify(options) { //創(chuàng)建一個圖形驗(yàn)證碼對象笨奠,接收options對象為參數(shù)
        this.options = { //默認(rèn)options參數(shù)值
            id: "", //容器Id
            canvasId: "verifyCanvas", //canvas的ID
            width: "100", //默認(rèn)canvas寬度
            height: "30", //默認(rèn)canvas高度
            type: "blend", //圖形驗(yàn)證碼默認(rèn)類型blend:數(shù)字字母混合類型、number:純數(shù)字店乐、letter:純字母
            code: ""
        }
        
        if(Object.prototype.toString.call(options) == "[object Object]"){//判斷傳入?yún)?shù)類型
            for(var i in options) { //根據(jù)傳入的參數(shù)艰躺,修改默認(rèn)參數(shù)值
                this.options[i] = options[i];
            }
        }else{
            this.options.id = options;
        }
        
        this.options.numArr = "0,1,2,3,4,5,6,7,8,9".split(",");
        this.options.letterArr = getAllLetter();
 
        this._init();
        this.refresh();
    }
 
    GVerify.prototype = {
        /**版本號**/
        version: '1.0.0',
        
        /**初始化方法**/
        _init: function() {
            var con = document.getElementById(this.options.id);
            var canvas = document.createElement("canvas");
            this.options.width = con.offsetWidth > 0 ? con.offsetWidth : "100";
            this.options.height = con.offsetHeight > 0 ? con.offsetHeight : "30";
            canvas.id = this.options.canvasId;
            canvas.width = this.options.width;
            canvas.height = this.options.height;
            canvas.style.cursor = "pointer";
            canvas.innerHTML = "您的瀏覽器版本不支持canvas";
            con.appendChild(canvas);
            var parent = this;
            canvas.onclick = function(){
                parent.refresh();
            }
        },
        
        /**生成驗(yàn)證碼**/
        refresh: function() {
            this.options.code = "";
            var canvas = document.getElementById(this.options.canvasId);
            if(canvas.getContext) {
                var ctx = canvas.getContext('2d');
            }else{
                return;
            }
            
            ctx.textBaseline = "middle";
 
            ctx.fillStyle = randomColor(180, 240);
            ctx.fillRect(0, 0, this.options.width, this.options.height);
 
            if(this.options.type == "blend") { //判斷驗(yàn)證碼類型
                var txtArr = this.options.numArr.concat(this.options.letterArr);
            } else if(this.options.type == "number") {
                var txtArr = this.options.numArr;
            } else {
                var txtArr = this.options.letterArr;
            }
 
            for(var i = 1; i <= 4; i++) {
                var txt = txtArr[randomNum(0, txtArr.length)];
                this.options.code += txt;
                ctx.font = randomNum(this.options.height/2, this.options.height) + 'px SimHei'; //隨機(jī)生成字體大小
                ctx.fillStyle = randomColor(50, 160); //隨機(jī)生成字體顏色        
                ctx.shadowOffsetX = randomNum(-3, 3);
                ctx.shadowOffsetY = randomNum(-3, 3);
                ctx.shadowBlur = randomNum(-3, 3);
                ctx.shadowColor = "rgba(0, 0, 0, 0.3)";
                var x = this.options.width / 5 * i;
                var y = this.options.height / 2;
                var deg = randomNum(-30, 30);
                /**設(shè)置旋轉(zhuǎn)角度和坐標(biāo)原點(diǎn)**/
                ctx.translate(x, y);
                ctx.rotate(deg * Math.PI / 180);
                ctx.fillText(txt, 0, 0);
                /**恢復(fù)旋轉(zhuǎn)角度和坐標(biāo)原點(diǎn)**/
                ctx.rotate(-deg * Math.PI / 180);
                ctx.translate(-x, -y);
            }
            /**繪制干擾線**/
            for(var i = 0; i < 4; i++) {
                ctx.strokeStyle = randomColor(40, 180);
                ctx.beginPath();
                ctx.moveTo(randomNum(0, this.options.width), randomNum(0, this.options.height));
                ctx.lineTo(randomNum(0, this.options.width), randomNum(0, this.options.height));
                ctx.stroke();
            }
            /**繪制干擾點(diǎn)**/
            for(var i = 0; i < this.options.width/4; i++) {
                ctx.fillStyle = randomColor(0, 255);
                ctx.beginPath();
                ctx.arc(randomNum(0, this.options.width), randomNum(0, this.options.height), 1, 0, 2 * Math.PI);
                ctx.fill();
            }
        },
        
        /**驗(yàn)證驗(yàn)證碼**/
        validate: function(code){
            var code = code.toLowerCase();
            var v_code = this.options.code.toLowerCase();
            console.log(v_code);
            if(code == v_code){
                return true;
            }else{
                this.refresh();
                return false;
            }
        }
    }
    /**生成字母數(shù)組**/
    function getAllLetter() {
        var letterStr = "a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z";
        return letterStr.split(",");
    }
    /**生成一個隨機(jī)數(shù)**/
    function randomNum(min, max) {
        return Math.floor(Math.random() * (max - min) + min);
    }
    /**生成一個隨機(jī)色**/
    function randomColor(min, max) {
        var r = randomNum(min, max);
        var g = randomNum(min, max);
        var b = randomNum(min, max);
        return "rgb(" + r + "," + g + "," + b + ")";
    }
    window.GVerify = GVerify;
})(window, document);
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市眨八,隨后出現(xiàn)的幾起案子腺兴,更是在濱河造成了極大的恐慌,老刑警劉巖廉侧,帶你破解...
    沈念sama閱讀 211,348評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件页响,死亡現(xiàn)場離奇詭異,居然都是意外死亡段誊,警方通過查閱死者的電腦和手機(jī)闰蚕,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,122評論 2 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來连舍,“玉大人没陡,你說我怎么就攤上這事。” “怎么了盼玄?”我有些...
    開封第一講書人閱讀 156,936評論 0 347
  • 文/不壞的土叔 我叫張陵贴彼,是天一觀的道長。 經(jīng)常有香客問我埃儿,道長器仗,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,427評論 1 283
  • 正文 為了忘掉前任童番,我火速辦了婚禮精钮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘剃斧。我一直安慰自己轨香,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,467評論 6 385
  • 文/花漫 我一把揭開白布悯衬。 她就那樣靜靜地躺著弹沽,像睡著了一般。 火紅的嫁衣襯著肌膚如雪筋粗。 梳的紋絲不亂的頭發(fā)上策橘,一...
    開封第一講書人閱讀 49,785評論 1 290
  • 那天,我揣著相機(jī)與錄音娜亿,去河邊找鬼丽已。 笑死,一個胖子當(dāng)著我的面吹牛买决,可吹牛的內(nèi)容都是我干的沛婴。 我是一名探鬼主播,決...
    沈念sama閱讀 38,931評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼督赤,長吁一口氣:“原來是場噩夢啊……” “哼嘁灯!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起躲舌,我...
    開封第一講書人閱讀 37,696評論 0 266
  • 序言:老撾萬榮一對情侶失蹤丑婿,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后没卸,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體羹奉,經(jīng)...
    沈念sama閱讀 44,141評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,483評論 2 327
  • 正文 我和宋清朗相戀三年约计,在試婚紗的時候發(fā)現(xiàn)自己被綠了诀拭。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,625評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡煤蚌,死狀恐怖耕挨,靈堂內(nèi)的尸體忽然破棺而出细卧,到底是詐尸還是另有隱情,我是刑警寧澤俗孝,帶...
    沈念sama閱讀 34,291評論 4 329
  • 正文 年R本政府宣布酒甸,位于F島的核電站,受9級特大地震影響赋铝,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜沽瘦,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,892評論 3 312
  • 文/蒙蒙 一革骨、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧析恋,春花似錦良哲、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至并村,卻和暖如春巍实,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背哩牍。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工棚潦, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人膝昆。 一個月前我還...
    沈念sama閱讀 46,324評論 2 360
  • 正文 我出身青樓丸边,卻偏偏與公主長得像,于是被迫代替她去往敵國和親荚孵。 傳聞我的和親對象是個殘疾皇子妹窖,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,492評論 2 348

推薦閱讀更多精彩內(nèi)容