js表单验证案例

本文展示了如何使用HTML和JavaScript实现一个注册页面,包括定时发送验证码的功能,以及表单验证,如用户名、手机号、验证码和密码的正则验证。此外,还涉及到防止多次点击发送验证码的问题和同意协议的验证。
摘要由CSDN通过智能技术生成

register复写.html(注册页面)

定时器发送验证码效果

表单验证

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <link rel="stylesheet" href="./css/common.css">
  <link rel="stylesheet" href="./css/register.css">
  <link rel="stylesheet" href="https://at.alicdn.com/t/font_2143783_iq6z4ey5vu.css">
</head>

<body>
  <div class="xtx-wrapper">
    <div class="container">
      <!-- 卡片 -->
      <div class="xtx-card">
        <h3>新用户注册</h3>
        <form class="xtx-form">
          <div data-prop="username" class="xtx-form-item">
            <span class="iconfont icon-user"></span>
            <input name="username" type="text" placeholder="设置用户名称">
            <span class="msg"></span>
          </div>
          <div data-prop="phone" class="xtx-form-item">
            <span class="iconfont icon-phone"></span>
            <input name="phone" type="text" placeholder="输入手机号码  ">
            <span class="msg"></span>
          </div>
          <div data-prop="code" class="xtx-form-item">
            <span class="iconfont icon-code"></span>
            <input name="code" type="text" placeholder="短信验证码">
            <span class="msg"></span>
            <a class="code" href="javascript:;">发送验证码</a>
          </div>
          <div data-prop="password" class="xtx-form-item">
            <span class="iconfont icon-lock"></span>
            <input name="password" type="password" placeholder="设置6至20位字母、数字和符号组合">
            <span class="msg"></span>
          </div>
          <div data-prop="confirm" class="xtx-form-item">
            <span class="iconfont icon-lock"></span>
            <input name="confirm" type="password" placeholder="请再次输入上面密码">
            <span class="msg"></span>
          </div>
          <div class="xtx-form-item pl50">
            <i class="iconfont icon-queren"></i>
            已阅读并同意<i>《用户服务协议》</i>
          </div>
          <div class="xtx-form-item">
            <button class="submit">下一步</button>
            <!-- <a class="submit" href="javascript:;">下一步</a> -->
          </div>
        </form>
      </div>
    </div>
  </div>
  <script>
    /*
     倒计时效果
     发送验证码
     1.用户点击之后,显示 '05秒后重新获取'
     2.利用间隙函数setInterval
     3.时间到了自动改为重新获取

     防止多次点击的问题
     定义一个开关变量,防止代码多次执行  flag = true
     1.点击之后,代码执行一次之后,先关闭开关,flag = false 防止代码多次执行
     2.倒计时结束,时间到了 打开开关 flag = true,可以执行下一次点击
    */
    const codeEle = document.querySelector('.code')
    let flag = true
    codeEle.addEventListener('click', function () {
      // 用标记位flag来解决定时器叠加的问题
      if (flag) {
        // 定时器秒数
        let i = 5
        // 设置初始状态
        codeEle.innerHTML = `${i}s后可重新获取`
        // 点击发送验证码开启定时器
        let timerId = setInterval(function () {
          i--
          codeEle.innerHTML = `${i}s后可重新获取`
          if (i === 0) {
            codeEle.innerHTML = `重新获取`
            clearInterval(timerId)
            // 定时器秒数为0时,要重新把标记位 置1,释放锁
            flag = true
          }
        }, 1000)
        // 定时器执行完后把标记位 置0,加锁,由于定时器会多次调用回调函数,在此期间如果再次点击发送验证码就不会开启定时器
        flag = false
      }
    })

    // 2.用户名验证(封装函数 validateName)
    // 1给input注册change事件,值被修改并且失去焦点后触发
    // 正则规则 /^[a-zA-Z0-9-_]{6,10}$/
    // 如果不符合要求 span出现提示消息  return false 中断程序
    // 如果正确返回 return true   之所以返回布尔值  为了点击提交再次验证
    const regName = /^[a-zA-Z0-9-_]{6,10}$/
    const nameIptEle = document.querySelector('[name=username]')
    nameIptEle.addEventListener('change', validateName)
    function validateName() {
      if (!regName.test(nameIptEle.value)) {
        nameIptEle.nextElementSibling.innerHTML = `请输入6-10位的数字、字母或_`
        return false
      } else {
        nameIptEle.nextElementSibling.innerHTML = ``
        return true
      }
    }


    // 手机号验证   /^(?:(?:\+|00)86)?1(?:(?:3[\d])|(?:4[5-79])|(?:5[0-35-9])|(?:6[5-7])|(?:7[0-8])|(?:8[\d])|(?:9[1589]))\d{8}$/
    const regPhone = /^(?:(?:\+|00)86)?1(?:(?:3[\d])|(?:4[5-79])|(?:5[0-35-9])|(?:6[5-7])|(?:7[0-8])|(?:8[\d])|(?:9[1589]))\d{8}$/
    const phoneIptEle = document.querySelector('[name=phone]')
    phoneIptEle.addEventListener('change', validatePhone)
    function validatePhone() {
      if (!regPhone.test(phoneIptEle.value)) {
        phoneIptEle.nextElementSibling.innerHTML = `请输入11位手机号`
        return false
      } else {
        phoneIptEle.nextElementSibling.innerHTML = ``
        return true
      }
    }


    // 验证码   /^\d{6}$/
    const regCode = /^\d{6}$/
    const codeIptEle = document.querySelector('[name=code]')
    codeIptEle.addEventListener('change', validateCode)
    function validateCode() {
      if (!regCode.test(codeIptEle.value)) {
        codeIptEle.nextElementSibling.innerHTML = `请输入6位数字验证码`
        return false
      } else {
        codeIptEle.nextElementSibling.innerHTML = ``
        return true
      }
    }


    // 密码   /^[a-zA-Z0-9-_]{6,20}$/
    const regPwd = /^[a-zA-Z0-9-_]{6,20}$/
    const pwdIptEle = document.querySelector('[name=password]')
    pwdIptEle.addEventListener('change', validatePwd)
    function validatePwd() {
      if (!regPwd.test(pwdIptEle.value)) {
        pwdIptEle.nextElementSibling.innerHTML = `请输入6-20位的密码,由数字、字母、下划线组成`
        return false
      } else {
        pwdIptEle.nextElementSibling.innerHTML = ``
        return true
      }
    }


    //  再次确认密码  验证条件 是否和密码保持一致
    const conIptEle = document.querySelector('[name=confirm]')
    conIptEle.addEventListener('change', validateConfirm)
    function validateConfirm() {
      if (conIptEle.value !== pwdIptEle.value | !conIptEle.value | !pwdIptEle.value) {
        conIptEle.nextElementSibling.innerHTML = `两次密码不一致`
        return false
      } else {
        conIptEle.nextElementSibling.innerHTML = ``
        return true
      }
    }


    /*
      已阅读同意协议
      1.注册点击事件,通过toggle切换类实现不同样式
      .icon-queren 
      .icon-queren2 选中样式
    */
    const queren = document.querySelector('.icon-queren')
    queren.addEventListener('click', function () {
      queren.classList.toggle('icon-queren2')
    })


    /*
      下一步提交验证业务
      1.使用submit提交事件
      2.如果没有勾选同意协议, 提示 ‘需要勾选’ 并且 要阻止提交行为
      元素.classList.contains() 看有没有包含某个类   有返回true  没有返回false
    */
    const form = document.querySelector('.xtx-form')
    form.addEventListener('submit', function (e) {
      if (!queren.classList.contains('icon-queren2')) {
        e.preventDefault()
        return alert('请先勾选同意协议')
      }
      console.log(validateName());
      if (!validateName()) { e.preventDefault() }
      if (!validatePhone()) { e.preventDefault() }
      if (!validatePwd()) { e.preventDefault() }
      if (!validateCode()) { e.preventDefault() }
      if (!validateConfirm()) { e.preventDefault() }
    })
  </script>
</body>

</html>

login复写.html(登陆页面)

tab切换

提示勾选同意协议,用户名存本地,进行页面跳转

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title> - 新鲜 惠民 快捷!</title>
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="renderer" content="webkit">
  <link rel="shortcut icon" href="../favicon.ico">
  <link rel="stylesheet" href="./css/common.css">
  <link rel="stylesheet" href="./css/login.css">
  <link rel="stylesheet" href="https://at.alicdn.com/t/font_2143783_iq6z4ey5vu.css">
</head>

<body>
  <!-- 登录头部 -->
  <div class="xtx-login-header">
    <!-- <h1 class="logo"></h1> -->
    <a class="home" href="./index.html">进入网站首页</a>
  </div>
  <!-- 登录内容 -->
  <div class="xtx-login-main">
    <div class="wrapper">
      <form action="" autocomplete="off">
        <div class="box">
          <div class="tab-nav">
            <a href="javascript:;" class="active" data-id="0">账户登录</a>
            <a href="javascript:;" data-id="1">二维码登录</a>
          </div>
          <div class="tab-pane">
            <div class="link">
              <a href="javascript:;">手机验证码登录</a>
            </div>
            <div class="input">
              <span class="iconfont icon-user"></span>
              <input required type="text" placeholder="请输入用户名称/手机号码" name="username">
            </div>
            <div class="input">
              <span class="iconfont icon-safe"></span>
              <input required type="password" placeholder="请输入密码" name="password">
            </div>
            <div class="agree">
              <label for="my-checkbox">
                <input type="checkbox" value="1" id="my-checkbox" class="remember" name="agree">
              </label>
              我已同意 <a href="javascript:;">《服务条款》</a href="javascript:;"><a>《服务条款》</a>
            </div>
            <div class="button clearfix">
              <button type="submit" class="dl">登 录</button>
              <!-- <a class="dl" href="./center.html">登 录</a> -->
              <a class="fl" href="./forget.html">忘记密码?</a>
              <a class="fr" href="./register.html">免费注册</a>
            </div>
          </div>
          <div class="tab-pane" style="display: none;">
            <img class="code" src="./images/code.png" alt="">
          </div>
        </div>
      </form>
    </div>
  </div>
  <!-- 登录底部 -->
  <div class="xtx-login-footer">
    <!-- 版权信息 -->
    <div class="copyright">
      <p>
        <a href="javascript:;">关于我们</a>
        <a href="javascript:;">帮助中心</a>
        <a href="javascript:;">售后服务</a>
        <a href="javascript:;">配送与验收</a>
        <a href="javascript:;">商务合作</a>
        <a href="javascript:;">搜索推荐</a>
        <a href="javascript:;">友情链接</a>
      </p>
      <p>CopyRight &copy; 小兔鲜儿</p>
    </div>
  </div>
  <script>
    /*
      tab切换   事件委托  排他思想
    */
    const tabNav = document.querySelector('.tab-nav')
    const tabPanes = document.querySelectorAll('.tab-pane')
    tabNav.addEventListener('click', function (e) {
      if (e.target.tagName === 'A') {
        document.querySelector('.active').classList.remove('active')
        e.target.classList.add('active')
        console.log(e.target.dataset.id);
        for (let i = 0; i < tabPanes.length; i++) {
          tabPanes[i].style.display = 'none'
        }
        tabPanes[e.target.dataset.id].style.display = 'block'
      }
    })

    /*
      点击登录可以跳转页面
      1.注册表单提交事件,阻止默认行为
      2.如果没有勾选同意,则提示要勾选
      3.required 属性可以让表单不能为空
      4.假设登录成功
        把用户名记录到本地存储中
        同时跳转到首页  location.href
    */
    const formEle = document.querySelector('form')
    const agreeEle = document.querySelector('[name=agree]')
    const usernameEle = document.querySelector('[name=username]')
    const pwdEle = document.querySelector('[name=password]')
    formEle.addEventListener('submit', function (e) {
      e.preventDefault()
      if (!agreeEle.checked) {
        return alert('请勾选同意协议')
      }
      localStorage.setItem('user-xx', usernameEle.value)
      location.href = 'index复写.html'
    })

  </script>
</body>
</html>

index复写.html(首页)

如果本地存储中没有登陆的用户名就显示立即登录和免费注册

如果本地存储中有登陆的用户名就显示用户名和退出

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <ul class="user">
        <li class="username"></li>
        <li><a href="login复写.html">退出</a></li>
    </ul>
    <ul>
        <li><a href="login复写.html" class="login">立即登录</a></li>
        <li><a href="register复写.html" class="register">免费注册</a></li>
    </ul>

</body>

<script>
    const usernameEle = document.querySelector('.username')
    usernameEle.innerHTML = localStorage.getItem('user-xx')
    const user = localStorage.getItem('user-xx')
    const userEle = document.querySelector('.user')
    const ulsEle = document.querySelectorAll('ul')
    // ul标签样式display属性设置为none,进行隐藏
    for (let i = 0; i < ulsEle.length; i++) {
        ulsEle[i].style.display = 'none'
    }
    // 如果本地存储中没有登陆的用户名就显示立即登录和免费注册
    if (!user) {
        userEle.nextElementSibling.style.display = 'block'
    } else { // 如果本地存储中有登陆的用户名就显示用户名和退出
        userEle.style.display = 'block'
    }
</script>

</html>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值