关闭

客户注册页--手机号验证--失败篇

标签: 设计
574人阅读 评论(0) 收藏 举报
分类:

断断续续做了3天这个了,期间学习到很多的知识,现在来一个汇总。先看以下效果图:


首先先从 html 模版文件开始讲起,还有我这里只是把整个页面的程序截取出来讲解,所以可能直接运行会失败。

<!--注册表单-->
<form  class="form-horizontal">
    <!--手机号验证,重点部分-->
    <div id="form_0_phonenumber" class="form-group">
        <label for="inputPassword3" class="col-sm-2 control-label">手机号验证:</label>
        <div class="col-sm-4">
            <!-- 手机号输入框 -->
            <input id="telephone" type="text" class="form-control" onpropertychange="replaceNotNumber(this)" oninput="replaceNotNumber(this)" placeholder="Telephone Number ">
            <!-- 获取验证码按钮以及验证码输入框 -->
            <div class="">
                <br>
                <input id="checked_button" type="button" class="btn btn-warning" onclick="identity()" value="验证手机号" disabled>
                <input id="identify_codng" placeholder="请输入验证码" onpropertychange="replaceNotNumber(this)" oninput="replaceNotNumber(this)" type="text">
                <span></span>
            </div>
        </div>
        <!--下面是显示提示信息的,是两个错误与正确的图标-->
        <div id="username_result" class="col-sm-4">
            <span id="true_telephone" class="btn-lg glyphicon glyphicon glyphicon-ok hidden" aria-hidden="true"></span>
            <span id="error_telephone" class="btn-lg glyphicon glyphicon glyphicon glyphicon-remove hidden" aria-hidden="true"></span>
        </div>
    </div>
</form>
这里的提示信息不是通过 jQuery 在客户端生成的,而是在加载页面时就在了,只不过设置为 hidden ,而且我用了 bootstrap 框架,所以其中的很多内容都是直接从框架的最基础模版修改过来的,所以很多代码我也不知道他是什么意思大笑

之后就是万恶的 js 了,起码3分之2的时间都在写这玩意。难过

按照需求来讲,既然是手机号码,那么输入框内部自然是只能输入数字了,所以需要为输入框设置这个事件:

 <input id="telephone" type="text" class="form-control" onpropertychange="replaceNotNumber(this)" oninput="replaceNotNumber(this)" placeholder="Telephone Number ">

onpropertychange 拆分来看,on,property,change--在,属性, 改变 的时候触发的事件,他比 change 好的一点是 change 一定要在失去焦点之后才能触发事件,不适合实时检测,而这个事件是在属性值改变时就会触发,可以随时监控用户输入,但是很可惜他只对 IE 浏览器有用

但是还有另一个跟他功能一样,但是可以给其他浏览器使用的事件 oninput ,也就是他后面跟着的那个,可以看到触发事件后处理函数都是一样的,这个函数如下:

function replaceNotNumber(hehe)
{
    var pattern = /[^0-9]/g;
    if (pattern.test(hehe.value))
    {
        hehe.value = hehe.value.replace(pattern, "");
    }
}
这个函数是从网上找来的,其实他做的很简单,调用 js 的正则对象的 test 方法,详细的解释看这个官网资料:点击打开链接,这个方法会返回 true 和 false,再来看他的正则表达式: [ ^ 0 - 9 ] ,表示匹配除了0到9的数字之外的内容,后面的那个 g 表示会对整个匹配对象进行匹配,结合起来就是,非数字输入会被匹配,进入函数被处理,而处理也很简单,将这个的非数字部分替换为空,这样就完成了输入一定为数字。

但是我们知道使用浏览器是可以关闭 js 的,万一有人就喜欢恶作剧的话,那么你这个 js 函数也是没有半点用处的,所以在服务器端还是要对这部分进行正则表达式匹配的,这个后面再讲。

确定输入为数字了,那么接下来就是确定该手机号是否正确了,最简单的一点衡量就是位数是否够,位数够的话,接下来就可以将其传回服务器端进行判断这个号码是否是已经注册的。这里使用输入框的 change 事件进行触发,我已经写上注释了,但是还是在这里讲解以下我设想的流程,便于理解下面的代码:

首先使用 ajax 将输入框内容传回服务器端,再来根据服务器端的处理结果显示不同的结果,具体的体现就是输入框后面会有文字及图标的显示来提示用户,如果该电话号码正确,则将去掉原来设置为 disabled 属性的按钮的的 disabled 属性去掉,并将文字修改为 ”获取验证码“ 。

<script type="text/javascript">
// 这里是调用 change 而不是 onprepertychange 或者 oninput,是因为需要等用户确定自己输入完成,而不是实时验证
$("#telephone").change(function () {
        // 得到输入框的值
        var $telephone = $("#telephone").val();
        // 得到显示正确的图标的 jquery 对象,后面要操控的
        var $nav_true = $("#true_telephone");
        // 错误的图标
        var $nav_error = $("#error_telephone");
        // 这个最外框的显示,根据验证结果显示不同的情况
        var $form = $("#form_0_phonenumber");
        // 调用 $jQuery 的 length 属性来获取长度
        if ($telephone.length != 11) {
            var $message = "请检查手机号是否正确";
            // 这个是自定义的 js 函数,根据结果来调正输出的
            mode_change(false, $nav_true, $nav_error, $message, $form);
            // 后面就不用继续执行了
            return false;
        }
        // 经过上面的简单筛选,一般情况下可以将数据发送到后台了,存心捣乱的广靠 js 你还能拦得住吗 :)
        // 标准的 ajax 的内容,这里我不讲了,不会的可以看前几篇文章里我有详细解释
        var $url = "http://localhost/trouble_i_am_in/index.php/Home/register/phone";
        $returnmessage = $.ajax({
            type: "post",
            url: $url,
            data: {
                "telephone": $telephone
            },
            // 接下来就是根据返回值来确认这个这个手机号的情况了
            success: function () {
                var $arr = jQuery.parseJSON($returnmessage.responseText);
                // 如果返回 1 表示该用户名已存在
                if ($arr['code'] == 1) {
                    var $message = "该手机号已注册";
                    mode_change(false, $nav_true, $nav_error, $message, $form);
                }
                // 这里的情况到后台部分再讲解 
                else if ($arr['code'] == 2 || $arr['code'] == 3) {
                    var $message = "输入有误";
                    mode_change(false, $nav_true, $nav_error, $message, $form);
                }
                // 验证此手机号正确且没有注册过 
                else {
                    mode_change(true, $nav_true, $nav_error, null, $form);
                    // 去除掉 获取验证码按钮的 disabled 属性,并修改文字显示
                    $("#checked_button").removeAttr("disabled");
                    $("#checked_button").val("获取验证码");
                }
            },
            error: function () {
                alert("服务器繁忙,请您稍后再提交");
            }
        });
    });
</script>
代码中的返回值 2 与 3 的情况就要从后台文件中来看了,现在来看2 和 3 代表着什么。

<?php
/**
 * 这个函数是验证手机号的第一步,保证其为纯数字且在数据库中不存在
 */
public function phone() {
    //获取输入值
    $telephone = $_POST['telephone'];
    $pattern = "/^[0-9]*$/";
    // 这里虽然在客户端进行过检测,但是如果使用浏览器关闭 js 的话还是会发送过来的,所以这里还需要再检测一遍
    if (strlen($telephone) != 11) {
        // 手机号长度不够
        $data['code'] = 2;
        // 使用正则表达式来验证此输入是否是数字
    } else if (preg_match($pattern, $telephone) == 0) { 
        // 输入非数字
        $data['code'] = 3;
    } else {
        // 现在来验证是否有此手机号
        $where['telephone'] = array('eq', $telephone);
        // 使用 count 来统计此号码是否已存在
        $result = M("Customer")->field("telephone")->where($where)->count();
        if ($result != 0) {
            // 表示该手机号已存在
            $data['code'] = 1;
        } else {
            // 该手机号正确
            $data['code'] = 0;
            // 使用 $_SESSION 来进行电话号码的存储,下面还要根据电话号码来进行发送短信验证此电话号码是否是本人
            //所有,直接在这里存储,就不用下次再进行一次验证
            $_SESSION['telephone'] = $telephone;
        }
    }
    $this->ajaxReturn($data, "json");
}
?>
下面就是我犯的一个写晕了才导致的一个问题,我这里还需要点击第二次按钮才会发送验证码短信。。。。。。。进入页面时的情景。



(“手机号验证”的字样以及输入框的颜色都变了表示该电话号码正确)这样其实用户就要多点击一次,先点击验证手机号,手机号验证正确,再来点击获取验证码,其实只需要用户点击一次获取验证码,之后再来验证用户输入框的内容就是了,这是我一时脑子乱造成的后果。尴尬但是我也是写到这里才发现这个 bug 的,所以我现在只能照着原思路往下写了,后面我会改的。

接着就写点击“获取验证码”的按钮之后执行的函数。

<script type="text/javascript">
var countdown=60;
// 点击 获取验证码 之后执行的 js 函数
function identity() {
    //前面已经缓存过用户输入的电话号码了,所以这里不需要再去记录输入框内容了,而且用户改变输入框内容
    //也会被重新验证,重新存储
    var $url = "http://localhost/trouble_i_am_in/index.php/Home/register/identify";
    $return_message = $.ajax({
        type: "post",
        url: $url,
        success: function () {
        // 成功的话这里开启定时显示 
            countdown=60;
            showTime();
        },
        error: function () {
            alert("服务器繁忙,请您稍后再提交");
        }
    });
}
// 显示倒计时
function showTime() {
    //这个按钮就是前面 “获取验证码” 的那个按钮
    $button=$("#checked_button");
    //countdown 在前面调用这个函数的时候就设置好了是60,而且他本身就是一个全局变量
    if(countdown==0){
        $button.val("重新获取验证码");
        $button.removeAttr("disabled");
    }else{
        //为了防止用户乱点按钮,将其设置为 disabled
        $button.attr("disabled",true);
        //改变按钮的文本内容,做倒计时
        $button.val(countdown+"s后无效");
        countdown--;
    }
    //我是第一次使用这个函数,但是还是感觉他好神奇
    //这个函数可以设置 showTime 每隔 1000 ms 即 1s 执行一次,正好能显示出倒计时效果
    setTimeout(function() { showTime() },1000);
}         
</script>
上面顺道把倒计时的函数也写出来了,很简单的,看看就懂了,之后就是这个 ajax 发送到的后台服务器文件了

<?php
/**
 * 这个函数是发送短信功能的
 */
public function identify() {
    //防止用户使用浏览器关闭 disabeled 之后直接点击按钮
    if($_SESSION['telephone']==null){
        //直接返回空值
        $this->ajaxReturn(null,'json');
    }
    else{
        // thinlphp 的单字母函数,可以缓存文件,可以既可以指定缓存类型以及为单个缓存对象
        //设置单独的缓存时间
        // 缓存这个验证码90秒,99秒后无效,不会与其他缓存的过期时间起冲突
        S('identify_coding',  identifying_code(4),90);
//            这里开始调用发送验证码的短信,只有100条,我实验过是成功,所以直接关闭掉了
//            $message=new Ecd($this->url,$this->app_key,$this->app_secret,$this->format);
//            $message->send_sms_code($_SESSION['telephone'],'396',S('identify_coding'));
        $this->ajaxReturn(null,'json');
    }  
}
?>
注意这里设置的缓存时间是 90 秒,前台显示是 60 秒,是为了考虑各种延时,所以后台设置时间长一点。

最后一部分了,验证码验证,做了这么多就是为了这一步。

还是 js 部分。

<script type="text/javascript">
//        发送验证码到后台验证
$('#identify_codng').focusout(function(){
    var $url = "http://localhost/trouble_i_am_in/index.php/Home/register/checkidentiry";
    var $ic=$('#identify_codng').val();
    //如果验证码位数不够
    if($ic.length!=4){
        return false;
    }
    $returnmessage=$.ajax({
        type:'post',
        url:$url,
        data:{
          'ic':$ic  
        },
        success:function(){
           var $arr = jQuery.parseJSON($returnmessage.responseText);
           if($arr['judge']!=3){
               alert("验证码输入有误");
           }
        },
        error:function(){
            alert("服务器繁忙,请您稍后提交");
        }
    });
});     
</script>
之后就是后台的处理。

<?php
public function checkidentiry(){
    $ic=$_POST['ic'];
    $number=  strlen($ic);
    //默认设置错误代码
    $data['judge']=1;
    if($numbe!=4){
      //返回默认错误代码
    }else if(S('identify_coding')==$ic){
        //验证正确
        $data['judge']=2;
        //将当前的电话号码存储为真正的电话号码
        $_SESSION['true_telephone']=$_SESSION['telephone'];
    }
    $this->ajaxReturn($data);
}
?>
自己一边写一边总结自己的这部分,发现自己的代码很乱,思路很混乱,而且有一些代码有冗余,还可以更精简一点,明天开始我会首先先解决上面自己提出的那个需要点击两次按钮的那个问题,再来总结一次。加油!!!
接着还有一个函数没贴出来,其实那个函数没有多大作用,但是还是可以省点力的。

// 一个自定义的函数,改变输入框的外观来展现结果
function mode_change($mode, $nav_true, $nav_error, $message, $form) {
    //以防万一,先把这个全部的节点恢复成原状,再在后面修改
    $form.removeClass("has-error");
    $form.removeClass("has-success");
    $nav_true.addClass("hidden");
    $nav_error.addClass("hidden");
    // true的话表示显示正确的图标,并且修改最外层的配置
    if ($mode == true) {
        $form.addClass("has-success");
        $nav_error.addClass("hidden");
        $nav_true.removeClass("hidden");
    } else {
        $form.addClass("has-error");
        $nav_true.addClass("hidden");
        $nav_error.removeClass("hidden");
        $nav_error.text($message);
    }
}








0
0

猜你在找
【直播】机器学习&数据挖掘7周实训--韦玮
【套餐】系统集成项目管理工程师顺利通关--徐朋
【直播】3小时掌握Docker最佳实战-徐西宁
【套餐】机器学习系列套餐(算法+实战)--唐宇迪
【直播】计算机视觉原理及实战--屈教授
【套餐】微信订阅号+服务号Java版 v2.0--翟东平
【直播】机器学习之矩阵--黄博士
【套餐】微信订阅号+服务号Java版 v2.0--翟东平
【直播】机器学习之凸优化--马博士
【套餐】Javascript 设计模式实战--曾亮
查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:59741次
    • 积分:1766
    • 等级:
    • 排名:千里之外
    • 原创:103篇
    • 转载:83篇
    • 译文:4篇
    • 评论:13条
    最新评论