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%
让登录按钮填满整个容器宽度。
关键知识点总结:
-
盒模型 :
padding
,border
,box-sizing
的使用 -
选择器进阶 :
:invalid
伪类、:has()
关系选择器 -
状态反馈:通过边框颜色/背景色变化提供用户反馈
-
响应式设计 :
max-width
+margin: 0 auto
实现自适应居中 -
过渡动画 :
transition
实现样式变化的平滑过渡 -
条件显示:利用选择器控制错误信息的显示逻辑
这些技术组合起来创建了一个具有良好用户体验的表单界面,能实时验证输入并给出明确反馈,适合新手学习表单设计的核心概念。
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
的值
特点
-
不会返回新数组 (与
map
不同) -
不能中断循环 (不能使用
break
或return
来中断) -
会跳过空位(稀疏数组中的空元素不会调用回调函数)
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()
:阻止表单自动提交和页面刷新 -
账户验证流程:
-
检查用户名 → 错误则弹出提示
-
检查邮箱 → 错误则弹出提示
-
检查密码 → 错误则弹出提示
-
全部正确 → 显示登录成功
-
-
注意 :代码中用户名变量有拼写错误 (
usename
应该是username
)
整体工作流程
-
页面加载时:
-
获取所有输入框和提交按钮
-
默认提交按钮是禁用状态
-
-
用户输入时:
-
实时检查每个字段的有效性
-
当所有字段符合要求时启用提交按钮
-
-
点击提交按钮时:
-
阻止默认表单提交
-
将用户输入与预设账户比较
-
根据验证结果弹出相应提示
-
关键概念解析
-
事件监听 (Event Listeners):
-
input
事件:在输入框值变化时触发 -
click
事件:在按钮点击时触发
-
-
表单验证 (Form Validation):
-
前端验证:提供即时反馈
-
HTML5验证:
validity.valid
使用浏览器内置验证规则
-
-
DOM操作:
-
getElementById()
:通过ID获取元素 -
value
属性:获取/设置输入框的值 -
disabled
属性:控制按钮状态
-
效果展示:
