HMTL
一个静态表单由如下几部分组成:
- 注册标题
- 各个input输入框
- 错误提示文本
- 提交按钮
<div class="formcontrol"> <label for="username">用户名</label> <input type="text" id="username" placeholder="请输入用户名"> <small>错误提示</small> </div>
这里我以用户名输入框为例来进行说明。首先是label标签,它不会向用户呈现特殊效果,但是它为鼠标用户改进了可用性。我们点击用户名这个文本的时候,input输入框会变成聚焦状态。
input输入框里面placeholder里面的文本,当input输入框未聚焦时消失,不聚焦则显示。最后是错误提示文本,我们默认visibility 为hidden,设置后相当于透明度为0 ,而display:none相当于此元素消失。
CSS
表单居中
将一个div水平垂直居中,我们可以将它的父元素设置为flex,然后再设置居中。这里body高度用的是100vh,表示占满屏幕,50vh则占屏幕高的一半,以此类推。
body { background-color: #f9fafb; font-family: Arial, Helvetica, sans-serif; display: flex; align-items: center; justify-content: center; /* 将body里面的各个元素,主轴交叉轴居中 */ /* 此案例body里面只有一个div元素 */ min-height: 100vh; /* 100vh占满屏幕,50vh占一半屏幕 */ }
默认细节
label是行内标签,如果需要给它设置上下margin,需要先display block。输入框是incline-block,呈现的效果是独占一行,但是输入框的宽度却不是100%width,很人性化。
input输入框聚焦时还有一个outline(有点影响美观,在border的外层,可以将其去掉 outline 0)。
状态切换
表单有正确错误两种状态,我们暂时如下规定:用户输入满足要求时,input框变绿色,输入不符合时,input变红色,显现错误提示信息。
我们可以先将颜色设置为变量:
:root { --success-color: #2ecc71; --error-color: #e74c3c; }
给各个表单框(formcontrol类)添加成功和错误类,到时候状态切换直接改类名即可。
符合要求,input输入框变绿。
.formcontrol.success input { border-color: #2ecc71; }
不符合要求,input变红,显示错误提示。
.formcontrol.error input { border-color: var(--error-color); } .formcontrol.error small { visibility: visible; }
如何切换类我们在js里面操作。
JS
检测事项
- username,email,password,password2(再次输入密码)不能为空
- username长度3到15
- password长度6到12
- password和password2需要一致
绑定时间
form.addEventListener("submit", function (e) { e.preventDefault(); //阻止默认事件发生 checkallinput([username, email, password, password2]); checklength(username, 3, 15); checklength(password, 6, 12); checkpassword(password,password2); });
我们提交时间,系统是有一个默认提交流程的,就像我们点击超链接会自动跳转一样。这里我们可以阻止默认事件
检验是否为空--checkallinput
function checkallinput(inputarr) { for (let i of inputarr) { // es6反单引号用于字符串拼接,有变量则用美元符号,里面也可以添函数 if (i.value.trim() === "") showerror(i, `${qg(i.placeholder)}不能为空`); else if (i.id == "email") { if (!checkemail(email.value)) showerror(i, "邮箱格式错误"); else showsuccess(i); } else showsuccess(i); } }
inputarr是一个表单元素数组(表单元素我们用document.elementgetbyid()获取).
下面是一个for循环遍历,for循环有两种 for (let i of arrinput) for(let i in arrinput) ,区别如下:
- 对于一般数组,for of 遍历的是数组元素,for in 遍历的是索引值,也就是0 1 2 3....
- 对于自定义对象,Map表,只能使用for in 获取key值,然后根据key获取value,不能使用for of.
代码里我是用了` `,这是es6语法,可以实现字符串拼接.加上${.....} 里面还可以放变量个函数,比如这里放就是函数。我们之前css里面不是设置了error和success类吗?现在就是
他们派上用场的时候了:showerror和showsuccess只需要做个类名处理即可,代码如下。
function showerror(input, message) { const formcontrol = input.parentElement; formcontrol.className = "formcontrol error"; const small = formcontrol.querySelector("small"); small.innerText = message; } function showsuccess(input) { const formcontrol = input.parentElement; formcontrol.className = "formcontrol success"; }
检测完是否为空后,对于邮箱我们还得检测格式,这里用正则表达式,返回bool值
function checkemail(email) { const re = /^([a-zA-Z\d])(\w|\-)+@[a-zA-Z\d]+\.[a-zA-Z]{2,4}$/; return re.test(String(email)); }
qg()这个函数作用是切割字符串,保证错误提示是"用户名不能为空",而不是"请输入用户名不能为空"
function qg(str) { return str.slice(3); // slice 是string 和array都有的方法 }
检测长度--checklength
function checklength(input, min, max) { if (input.value.length < min) { showerror(input, `${qg(input.placeholder)}最小长度为${min}`); } else if (input.value.length > max) { showerror(input, `${qg(input.placeholder)}最大长度为${max}`); } else showsuccess(input); }
检测两次密码一致性--checkpassword
function checkpassword(p1,p2){ if(p1.value!= p2.value) showerror(p2,`两次密码输入不一致`) }
效果图