Web前端:JavaScript和CSS实现的基础登录验证功能

HTML代码:

html 复制代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>登录</title>
    <link rel="stylesheet" href="./css/css.css">
</head>
<body>
    <h1>登录</h1>

    <form>
        <div class="form-group">
            <label for="username">用户名</label>
            <input type="text" id="username" name="username" required minlength="4">
            <div class="error-message">用户名必须至少包含4个字符</div>
        </div>
        <div class="form-group">
            <label for="email">电子邮件</label>
            <input type="email" id="email" name="email" required>
            <div class="error-message">请输入有效的电子邮件地址</div>
        </div>
        
        <div class="form-group">
            <label for="password">密码</label>
            <input type="password" id="password" name="password" required pattern=".{8,}">
            <div class="error-message">密码必须至少8个字符</div>
        </div>
        
        <button disabled class="submit" id="submit" type="submit">提交</button>
    </form>

    <!-- JavaScript的代码 -->
    <script src="./js/index.js">
      
    </script>
</body>
</html>

CSS代码:

css 复制代码
/* 基础样式 */
body {
    font-family: Arial, sans-serif;
    max-width: 600px;
    margin: 0 auto;
    padding: 20px;
}

/* h1的样式 */
h1 {
    width: 100%;
    text-align: center;
}

.form-group {
    margin-bottom: 20px;
    padding: 15px;
    border-radius: 5px;
    border: 1px solid #ddd;
    transition: all 0.3s ease;
}

label {
    display: block;
    margin-bottom: 5px;
    font-weight: bold;
}

input {
    width: 100%;
    padding: 8px;
    border: 1px solid #ccc;
    border-radius: 4px;
    box-sizing: border-box;
}

input:invalid {
    border-color: #ff6b6b;
}

/* 当包含无效输入时高亮父容器 */
.form-group:has(input:invalid) {
    border-color: #ff6b6b;
    background-color: #fff5f5;
    box-shadow: 0 0 0 2px rgba(255, 107, 107, 0.2);
}

button {
    background-color: #4CAF50;
    color: white;
    padding: 10px 15px;
    border: none;
    border-radius: 4px;
    cursor: pointer;
}

button:hover {
    background-color: #45a049;
}

.error-message {
    color: #ff6b6b;
    font-size: 0.8em;
    margin-top: 5px;
    display: none;
}

/* 当输入无效时显示错误消息 */
.form-group:has(input:invalid) .error-message {
    display: block;
}


/* 登录按钮 */
.submit {
    width: 100%;
}

CSS代码解析 :

css 复制代码
/* 基础样式 */
body {
  font-family: Arial, sans-serif; /* 设置页面默认字体 */
  max-width: 600px;              /* 页面内容最大宽度 */
  margin: 0 auto;                /* 页面居中显示 */
  padding: 20px;                 /* 内边距 */
}

解释 :设置整个页面的基础样式。font-family定义默认字体,max-width限制内容宽度使布局更友好,margin: 0 auto实现水平居中,padding提供内容与边缘的间距。

css 复制代码
/* h1的样式 */
h1 {
  width: 100%;         /* 占满容器宽度 */
  text-align: center;  /* 文字居中 */
}

解释 :设置一级标题样式。width: 100%让标题撑满容器,text-align: center使文字居中显示。

css 复制代码
/* 表单组样式 */
.form-group {
  margin-bottom: 20px;  /* 组间间距 */
  padding: 15px;        /* 内边距 */
  border-radius: 5px;   /* 圆角边框 */
  border: 1px solid #ddd; /* 浅灰色边框 */
  transition: all 0.3s ease; /* 平滑过渡效果 */
}

解释 :表单组的容器样式。设置间距、内边距和边框,border-radius创建圆角效果,transition为后续的样式变化添加动画过渡。

css 复制代码
label {
  display: block;       /* 块级元素(独占一行) */
  margin-bottom: 5px;   /* 标签与输入框间距 */
  font-weight: bold;    /* 加粗文字 */
}

解释 :表单标签样式。display: block让标签单独占据一行,font-weight: bold使文字加粗更醒目。

css 复制代码
input {
  width: 100%;          /* 撑满容器 */
  padding: 8px;         /* 内边距 */
  border: 1px solid #ccc; /* 边框 */
  border-radius: 4px;   /* 圆角 */
  box-sizing: border-box; /* 盒模型计算方式 */
}

input:invalid {         /* 无效输入状态 */
  border-color: #ff6b6b; /* 红色边框 */
}

解释 :输入框基础样式。width: 100%让输入框填满容器,box-sizing: border-box确保宽度包含边框和内边距。input:invalid是CSS伪类选择器,当输入不合法时显示红色边框。

css 复制代码
/* 当包含无效输入时高亮父容器 */
.form-group:has(input:invalid) {
  border-color: #ff6b6b;       /* 红色边框 */
  background-color: #fff5f5;   /* 浅红背景 */
  box-shadow: 0 0 0 2px rgba(255, 107, 107, 0.2); /* 发光效果 */
}

解释 :高级选择器用法。:has()选择器查找包含无效输入框的表单组,为其添加红色边框、浅红背景和发光效果,实现整体高亮提示。

css 复制代码
button {
  background-color: #4CAF50; /* 绿色背景 */
  color: white;             /* 白色文字 */
  padding: 10px 15px;       /* 内边距 */
  border: none;             /* 无边框 */
  border-radius: 4px;       /* 圆角 */
  cursor: pointer;          /* 手型指针 */
}

button:hover {              /* 鼠标悬停状态 */
  background-color: #45a049; /* 深绿色 */
}

解释 :按钮基础样式与交互状态。设置按钮颜色、形状,cursor: pointer让鼠标悬停时显示手型图标,:hover伪类实现鼠标悬停时的颜色加深效果。

css 复制代码
.error-message {
  color: #ff6b6b;        /* 红色文字 */
  font-size: 0.8em;      /* 小号字体 */
  margin-top: 5px;       /* 顶部间距 */
  display: none;         /* 默认隐藏 */
}

/* 当输入无效时显示错误消息 */
.form-group:has(input:invalid) .error-message {
  display: block;        /* 显示错误信息 */
}

解释 :错误提示样式。默认隐藏错误信息(display: none),当表单组包含无效输入时,通过:has()选择器将错误信息设为display: block使其显示。

css 复制代码
/* 登录按钮 */
.submit {
  width: 100%;           /* 撑满容器 */
}

解释 :提交按钮的特殊样式。width: 100%让登录按钮填满整个容器宽度。

关键知识点总结:

  1. 盒模型padding, border, box-sizing的使用

  2. 选择器进阶:invalid伪类、:has()关系选择器

  3. 状态反馈:通过边框颜色/背景色变化提供用户反馈

  4. 响应式设计max-width + margin: 0 auto实现自适应居中

  5. 过渡动画transition实现样式变化的平滑过渡

  6. 条件显示:利用选择器控制错误信息的显示逻辑

这些技术组合起来创建了一个具有良好用户体验的表单界面,能实时验证输入并给出明确反馈,适合新手学习表单设计的核心概念。

JS代码:

javascript 复制代码
// 获取所有输入元素
const inputs = document.querySelectorAll('input');
const submitButton = document.getElementById("submit");

// 为每个输入添加事件监听
inputs.forEach(input => {
    input.addEventListener('input', function () {
        // 检查所有字段是否有效
        const isUsernameValid = document.getElementById("username").value.length >= 4;
        const isEmailValid = document.getElementById("email").validity.valid;
        const isPasswordValid = document.getElementById("password").value.length >= 8;

        // 启用或禁用按钮
        submitButton.disabled = !(isUsernameValid && isEmailValid && isPasswordValid);
    });
});

document.getElementById("submit").addEventListener("click", (event) => {
    event.preventDefault();
    const name = '一只小风华';
    const E_mail = '3024798541@qq.com';
    // 注意这里应该是字符串,因为输入的值是字符串
    const pswd = '12345678';

    const usename = document.getElementById("username").value;
    const email = document.getElementById("email").value;
    const password = document.getElementById("password").value;

    // 账户判断
    if (usename != name) {
        alert("用户名不正确")
    } else if (email != E_mail) {
        alert('电子邮箱不正确')
    } else if (password != pswd) {
        alert('密码不正确')
    } else {
        alert('登录成功!');

    }
});

JS代码解析:

1. 获取页面元素

javascript 复制代码
// 获取所有输入元素
const inputs = document.querySelectorAll('input');
const submitButton = document.getElementById("submit");
  • document.querySelectorAll('input'):选择页面中所有的 <input> 元素(输入框)

  • document.getElementById("submit"):获取ID为 "submit" 的按钮元素

  • 作用:为后续操作准备所需的DOM元素

2. 实时表单验证

javascript 复制代码
inputs.forEach(input => {
    input.addEventListener('input', function () {
        // 检查所有字段是否有效
        const isUsernameValid = document.getElementById("username").value.length >= 4;
        const isEmailValid = document.getElementById("email").validity.valid;
        const isPasswordValid = document.getElementById("password").value.length >= 8;

        // 启用或禁用按钮
        submitButton.disabled = !(isUsernameValid && isEmailValid && isPasswordValid);
    });
});
  • 功能:为每个输入框添加输入事件监听器

  • 验证逻辑

    • 用户名:长度 ≥ 4字符 (value.length >= 4)

    • 邮箱:使用浏览器内置验证 (validity.valid)

    • 密码:长度 ≥ 8字符 (value.length >= 8)

  • 按钮状态 :当所有验证通过时启用提交按钮(使用逻辑与 && 判断)

扩展内容

forEach 是 JavaScript 数组的一个内置方法,用于对数组的每个元素执行一次给定的函数。

基本语法
javascript 复制代码
array.forEach(function(currentValue, index, array) {
  // 执行的操作
}, thisArg);
参数说明
  • 回调函数:对每个元素执行的函数,接收三个参数:

    • currentValue:当前处理的元素

    • index(可选):当前元素的索引

    • array(可选):正在遍历的数组本身

  • thisArg (可选):执行回调时用作 this 的值

特点
  1. 不会返回新数组 (与 map 不同)

  2. 不能中断循环 (不能使用 breakreturn 来中断)

  3. 会跳过空位(稀疏数组中的空元素不会调用回调函数)

3. 提交处理

javascript 复制代码
document.getElementById("submit").addEventListener("click", (event) => {
    event.preventDefault(); // 阻止表单默认提交行为
    
    // 预设的正确账户信息
    const name = '一只小风华';
    const E_mail = '3024798541@qq.com';
    const pswd = '12345678';

    // 获取用户输入值
    const usename = document.getElementById("username").value;
    const email = document.getElementById("email").value;
    const password = document.getElementById("password").value;

    // 账户验证逻辑
    if (usename != name) {
        alert("用户名不正确")
    } else if (email != E_mail) {
        alert('电子邮箱不正确')
    } else if (password != pswd) {
        alert('密码不正确')
    } else {
        alert('登录成功!');
    }
});
  • event.preventDefault():阻止表单自动提交和页面刷新

  • 账户验证流程

    1. 检查用户名 → 错误则弹出提示

    2. 检查邮箱 → 错误则弹出提示

    3. 检查密码 → 错误则弹出提示

    4. 全部正确 → 显示登录成功

  • 注意 :代码中用户名变量有拼写错误 (usename 应该是 username)

整体工作流程

  1. 页面加载时

    • 获取所有输入框和提交按钮

    • 默认提交按钮是禁用状态

  2. 用户输入时

    • 实时检查每个字段的有效性

    • 当所有字段符合要求时启用提交按钮

  3. 点击提交按钮时

    • 阻止默认表单提交

    • 将用户输入与预设账户比较

    • 根据验证结果弹出相应提示

关键概念解析

  1. 事件监听 (Event Listeners)

    • input 事件:在输入框值变化时触发

    • click 事件:在按钮点击时触发

  2. 表单验证 (Form Validation)

    • 前端验证:提供即时反馈

    • HTML5验证:validity.valid 使用浏览器内置验证规则

  3. DOM操作

    • getElementById():通过ID获取元素

    • value 属性:获取/设置输入框的值

    • disabled 属性:控制按钮状态

效果展示:

相关推荐
小莫分享6 分钟前
Chrome更新后,扩展不能用问题
前端·chrome
zhangxxxq8 分钟前
前端vue3获取excel二进制流在页面展示
前端·excel
Kiri霧25 分钟前
Kotlin集合分组
android·java·前端·kotlin
拾光拾趣录36 分钟前
举一反三:合并 K 个有序链表的最小堆实现
前端·算法
拾光拾趣录1 小时前
合并K个有序链表
前端·算法
江城开朗的豌豆1 小时前
Event Bus:Vue组件间的'广播电台',轻松实现跨组件通信!
前端·javascript·vue.js
袁煦丞1 小时前
7.18实验室 碎片灵感秒同步!memos让笔记追着你跑:cpolar内网穿透第613个成功挑战
前端·程序员·远程工作
江城开朗的豌豆1 小时前
插槽:Vue里的‘占位符’,让组件更灵活!
前端·javascript·vue.js
江城开朗的豌豆1 小时前
$nextTick vs 定时器:Vue的'等一等'和JS的'睡一会'有啥区别?
前端·javascript·vue.js
三月的一天1 小时前
用 React-Three-Fiber 实现雪花下落与堆积效果:从零开始的 3D 雪景模拟
前端·react.js·前端框架