注册表单案例

发布于:2025-07-20 ⋅ 阅读:(12) ⋅ 点赞:(0)

注册表单功能案例

效果如下:
在这里插入图片描述

一、表单基础结构与元素获取

1. HTML结构设计

注册表单需包含用户输入项(用户名、手机号、验证码等)、验证提示区(错误/正确信息)和操作按钮(获取验证码、提交)
将每个区域的内容都包起来,便于获取元素。

<form class="info">
  <!-- 用户名输入 -->
  <div class="uname">
    <input type="text" name="uname" placeholder="用户名">
    <!-- 提示区 -->
    <p class="unamep"></p> 
  </div>
  <!-- ... -->
  <button>下一步</button>
</form>

2. JS获取DOM元素

//获取表单元素
const info = document.querySelector('.info');
// 获取用户名相关元素
const uname = document.querySelector('.uname input');
const unamep = document.querySelector('.uname p');
// ...

二、表单验证功能实现(以密码为例)

通过正则表达式验证“input中得到输入值校验→提示反馈→返回验证结果”,确保输入符合规则,包括密码长度,重复密码的校验

1. 验证逻辑设计

以密码验证为例,需求:密码需为6-20位字母/[a-zA-Z0-9]{6,20}/。实现步骤:

验证函数
function checkPut(put) {
//定义规则
            const law = /[a-zA-Z0-9]{6,20}/;
            if (law.test(put.value)) {
                putp.innerHTML = '验证正确';
                putp.className = 'green';
            } else {
                putp.innerHTML = '昵称长度为6~20个字符';
                putp.className = 'red';
            }
            // 返回验证结果(true/false),用于后续整体提交校验
            return law.test(put.value);
        }
  • 用正则表达式定义校验规则;
  • 通过test方法检测输入值是否符合规则;
  • 实时更新提示区内容和样式(gree/red类),给用户直观反馈;
绑定失去焦点事件

当用户输入完成并离开输入框(失去焦点)时触发验证:

uname.addEventListener('blur', checkUname);

2. 其他输入项验证扩展

同理可实现手机号、验证码的验证,仅需调整正则规则和提示信息:

function checkReput() {
			//reput符合规则并且上一个密码一致
            return (checkPut(reput) && (put.value === reput.value)) ? true : false;
        }
        reput.addEventListener('blur', function () {
            if (checkReput()) {
                putp.innerHTML = '验证正确';
                //使用className 只添加一个类名
                //结构比较简单可以直接使用,避免使用classLIst使用的样式重叠
                putp.className = 'green';
            } else {
                putp.innerHTML = '输入错误或与上次输入的密码不一致';
                putp.className = 'red';
            }
        });

二、倒计时实现

实现“点击获取→按钮禁用→倒计时显示→时间结束恢复可用”。

倒计时核心函数

function startCountdown(duration, onUpdate, onComplete) {
// 总时长
  let seconds = duration; 
  onUpdate(seconds);

  // 每秒执行一次
  const countdownTimer = setInterval(() => {
    seconds--;
    onUpdate(seconds); // 传递当前剩余秒数
    if (seconds <= 0) {
      clearInterval(countdownTimer); 
      onComplete(); 
    }
  }, 1000);
}

绑定“获取验证码”按钮事件

const getcode = document.querySelector('.code span');

getcode.addEventListener('click', () => {
  // 1. 禁用按钮,防止重复点击
  getcode.disabled = true;
  getcode.classList.remove('lightgreen'); // 移除可点击样式
  getcode.classList.add('gray'); // 添加禁用样式
  getcode.style.cursor = 'not-allowed';

  // 2. 开始3秒倒计时
  startCountdown(3,
    // 每秒更新:显示剩余时间
    (seconds) => {
      codep.innerHTML = `还有${seconds}秒结束`;
    },
    // 倒计时结束:恢复按钮状态
    () => {
      codep.textContent = ''; // 清空提示
      getcode.disabled = false;
      getcode.classList.remove('gray');
      getcode.classList.add('lightgreen');
      getcode.style.cursor = 'pointer';
    }
  );
});

三、表单整体提交控制

阻止默认提交行为

表单默认提交会刷新页面,需先阻止:

const info = document.querySelector('.info');
info.addEventListener('submit', function (e) {
  e.preventDefault(); // 阻止默认提交

});

访问验证条件

提交前需检查所有输入项的验证结果(用户名、手机号、验证码、密码、同意条款等):

info.addEventListener('submit', function (e) {
  e.preventDefault();
  
 if (!checkCheck() || !checkNumber() || !checkCode() || !checkPut(put) || !checkReput() || !checkCheck()) {
                alert('请输入完整');
            } else {
                if (confirm('将在2秒后跳转')) {
                    setTimeout(function () {
                        location.href = 'https://www.baidu.com';
                    }, 2000)
                } else {
                    console.log('取消跳转');
                }
            }
});
end完整代码
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        body {
            padding: 0;
            margin: 0;
            background-color: rgb(231, 231, 231);
        }

        .w {
            width: 800px;
            height: 600px;
            margin: 0 auto;
            background-color: #fff;
        }

        h3 {
            height: 50px;
            font-size: 30px;
        }

        .contain {
            /* display: flex; */
            /* display: inline-block; */
            width: 300px;
            height: 500px;
            padding-left: 250px;
            /* background-color: pink; */
        }

        .contain .info div {
            display: flex;
            position: relative;
        }

        .contain .info div p {
            position: absolute;
            text-wrap: nowrap;
            top: -10px;
            left: 320px;
        }

        input {
            width: 300px;
            height: 40px;
            border: 1px solid black;
            margin-bottom: 20px;
            padding-left: 20px;
            outline: none;
        }

        .info .code {
            position: relative;
        }

        .info .code span {
            position: absolute;
            top: 10px;
            right: 5px;
            cursor: pointer;
        }

        .info .agree {
            display: flex;
            padding: 0 20px 0 20px;
        }

        .info .agree input {
            height: 20px;
        }

        .info .agree span {
            text-wrap: nowrap;
        }

        .contain .info button {
            width: 300px;
            height: 40px;
        }

        .green {
            color: green;
        }

        .red {
            color: red;
        }

        .lightgreen {
            color: lightgreen;
        }

        .gray {
            color: gray;
        }
    </style>
</head>

<body>
    <div class="w">
        <h3>新用户注册</h3>
        <div class="contain">
            <form action="" name="info" class="info" autocomplete="on">
                <div class="uname">
                    <input type="text" name="uname" placeholder="用户名">
                    <p class="unamep"></p>
                </div>
                <div class="phone">
                    <input type="text" name="phone" placeholder="手机号码">
                    <p class="phonep"></p>
                </div>
                <div class="code">
                    <input type="text" name="code" placeholder="短信验证码">
                    <span name="send" class="lightgreen">获得验证码</span>
                    <p class="codep"></p>
                </div>
                <div class="put">
                    <input type="password" name="pwd" id="" placeholder="设置6-20位密码没数字和符号组合" class="put">
                    <p class="pwdp"></p>
                </div>
                <div class="reput">
                    <input type="password" name="pwd" id="" placeholder="确认您的密码" class="reput">
                </div>
                <div class="agree">
                    <input type="checkbox" name="" id=""><span>&lt;&lt;已同意并阅读用户服务协议&gt;&gt;</span>
                    <p class="agreep"></p>
                </div>
                <button>下一步</button>
            </form>
            <div class="tips">

            </div>
        </div>
    </div>
    <script>
        const info = document.querySelector('.info');
        // 
        const uname = document.querySelector('.uname input');
        const unamep = document.querySelector('.uname p');
        // 
        const number = document.querySelector('.phone input');
        const numberp = document.querySelector('.phone p');
        // 
        const code = document.querySelector('.info .code input');
        const codep = document.querySelector('.info .code p');
        const getcode = document.querySelector('.info .code span');
        // 
        const put = document.querySelector('.info .put input');
        const putp = document.querySelector('.info .put p');
        const reput = document.querySelector('.info .reput input');
        // 
        const agree = document.querySelector('.info .agree input');
        const agreep = document.querySelector('.info .agree p');
        // 
        const btn = document.querySelector('.info button');
        // 
        function checkUname() {
            const law = /[a-zA-Z]{6,10}/;
            if (law.test(uname.value)) {
                unamep.innerHTML = '验证正确';
                unamep.className = 'green';
            } else {
                unamep.innerHTML = '昵称长度为6~10个字符';
                unamep.className = 'red';
            }
            return law.test(uname.value);
        }
        uname.addEventListener('blur', checkUname);
        function checkNumber() {
            const law = /[1-9][0-9]{4,10}/;
            if (law.test(number.value)) {
                numberp.innerHTML = '验证正确';
                numberp.className = 'green';
            } else {
                numberp.innerHTML = '请输入正确的手机号';
                numberp.className = 'red';
            }
            return law.test(number.value);
        }
        number.addEventListener('blur', checkNumber);
        function checkCode() {
            const law = /[0-9]{6}/;
            if (law.test(code.value)) {
                codep.innerHTML = '验证正确';
                codep.className = 'green';
            } else {
                codep.innerHTML = '请输入正确的验证码';
                codep.className = 'red';
            }
            return law.test(code.value);
        }
        code.addEventListener('blur', checkCode);
        //
        function startCountdown(duration, onUpdate, onComplete) {
            let seconds = duration;
            onUpdate(seconds);

            // 设置每秒更新一次
            countdownTimer = setInterval(() => {
                seconds--;
                onUpdate(seconds);
                if (seconds <= 0) {
                    clearInterval(countdownTimer);
                    onComplete();
                }
            }, 1000);
        }
        getcode.addEventListener('click', () => {
            getcode.disabled = true;
            getcode.classList.remove('lightgreen');
            getcode.classList.add('gray');
            codep.innerHTML = ``;
            // 开始3秒倒计时
            startCountdown(3,
                // 更新回调:显示剩余秒数
                (seconds) => {
                    codep.innerHTML = `还有${seconds}秒结束`;
                    getcode.style.cursor = 'not-allowed';
                },
                // 完成回调:倒计时结束后执行
                () => {
                    codep.textContent = '';
                    getcode.disabled = false;
                    getcode.classList.remove('gray');
                    getcode.classList.add('lightgreen');
                    getcode.style.cursor = 'pointer';
                }
            );
        });
        // 
        function checkPut(put) {
            const law = /[a-zA-Z0-9]{6,20}/;
            if (law.test(put.value)) {
                putp.innerHTML = '验证正确';
                putp.className = 'green';
            } else {
                putp.innerHTML = '昵称长度为6~20个字符';
                putp.className = 'red';
            }
            return law.test(put.value);
        }
        put.addEventListener('blur', function () {
            checkPut(put);
        });
        function checkReput() {
            return (checkPut(reput) && (put.value === reput.value)) ? true : false;
        }
        reput.addEventListener('blur', function () {
            if (checkReput()) {
                putp.innerHTML = '验证正确';
                putp.className = 'green';
            } else {
                putp.innerHTML = '输入错误或与上次输入的密码不一致';
                putp.className = 'red';
            }
        });
        // 
        function checkCheck() {
            if (agree.checked === false) {
                agreep.innerHTML = '请先勾选按钮';
                agreep.classList.add('red');
            } else {
                agreep.innerHTML = '';
            }
            return agree.checked;
        }
        agree.addEventListener('change', checkCheck);
        // 
        info.addEventListener('submit', function (e) {
            // console.log('1');
            e.preventDefault();
            if (!checkCheck() || !checkNumber() || !checkCode() || !checkPut(put) || !checkReput() || !checkCheck()) {
                alert('请输入完整');
            } else {
                if (confirm('将在2秒后跳转')) {
                    setTimeout(function () {
                        location.href = 'https://www.baidu.com';
                    }, 2000)
                } else {
                    console.log('取消跳转');
                }
            }
        });
    </script>
</body>

</html>


网站公告

今日签到

点亮在社区的每一天
去签到