原生js单点登录表单验证,含验证码
特点:
1、原生js
2、SSO单点登录
3、含ajax请求的验证码
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>登录</title>
<link rel="stylesheet" href="./login.css">
</head>
<body>
<div class="loginView">
<div class="login-container">
<div class="login-title">用户登录</div>
<!-- -->
<form class="form-box" action="/login" method="post" onsubmit="return validateForm();">
<div class="item">
<label for="username" class="form-tip">账号</label>
<!-- required="required" -->
<input name="username" placeholder="请输入账号" id="username" type="text" >
</div>
<div class="item">
<label for="pwd" class="form-tip">密码</label>
<input id="pwd" placeholder="请输入密码" name="password" type="password" >
</div>
<div class="item veri_code">
<input id="veri_code" placeholder="请输入验证码" name="veri_code" type="text" >
<img id="veri_code_img" src="" alt="">
</div>
<button type="submit" class="login-btn">登录</button>
</form>
</div>
</div>
<!-- 提示框 -->
<div class="auto-tip-box">
<span class="icon">!</span>
<span class="auto-tip-desc">Warning text</span>
</div>
<!-- module 处理es6的import -->
<!-- <script type="module" src="./login.js">
这种方式就必须用export
</script> -->
<!-- <script src="./loginApi.js">
这种方式就不能用export
</script> -->
<script src="./loginApi.js"></script>
<script src="./login.js"></script>
</body>
</html>
css
* {
margin: 0;
padding: 0;
}
html,
body {
width: 100%;
height: 100%;
}
button,
input {
border: none;
outline: none;
}
.loginView {
width: 100%;
height: 100%;
background: url('./public.jpg') no-repeat;
background-size: 100% 100%;
position: relative;
}
.login-container {
position: absolute;
right: 12%;
border: 1px solid #FFFFFF;
box-sizing: border-box;
border-radius: 3px;
/* top: 34%; */
top: 32%;
width: 172px;
/* height: 184px;
overflow: hidden; */
}
.login-title {
text-align: center;
padding-bottom: 5px;
border-bottom: 3px solid rgba(245, 245, 245, 0.6);
margin: 12px auto 7px;
font-size: 0.8125rem;
color: #FFFFFF;
width: 112px;
}
.form-box {
box-sizing: border-box;
padding: 0px 13px;
}
.item input {
width: 145px;
height: 25px;
background-color: transparent;
border: 0.834952px solid #FFFFFF;
box-sizing: border-box;
border-radius: 1.6699px;
/* padding-left: 0.75rem; */
padding-left: 5px;
outline: none;
/* font-size: 0.625rem; */
font-size: 10px;
}
.item input::placeholder {
padding-left: -0.75rem;
color: #E3E4E5;
font-size: 10px;
}
.item .form-tip {
font-size: 0.625rem;
line-height: 0.8125rem;
color: #E3E4E6;
margin-bottom: 0.146875rem;
}
.login-btn {
cursor: pointer;
width: 145px;
margin-bottom: 12.75px;
margin-top: 14.18px;
height: 22px;
background: #4473ea;
border-radius: 2px;
display: flex;
justify-content: center;
align-items: center;
color: #ffffff;
font-size: 0.6347rem;
font-family: 'Microsoft YaHei UI';
}
.veri_code {
width: 145px;
height: 25px;
margin-top: 6px;
display: flex;
align-items: center;
justify-content: space-between;
cursor: pointer;
}
.veri_code #veri_code {
width: 55%;
}
.veri_code img {
width: 40%;
height: 100%;
object-fit: cover;
}
/* 提示框 */
.auto-tip-box {
display: none;
position: fixed;
top: 150px;
left: 50%;
z-index: 999;
width: 300px;
height: 40px;
line-height: 40px;
margin-left: -150px;
background-color: #fffbe6;
padding-left: 24px;
border-radius: 2px;
font-size: 12px;
}
.auto-tip-box .icon {
display: inline-block;
width: 14px;
height: 14px;
border-radius: 50%;
background-color: orange;
color: #fff;
line-height: 14px;
text-align: center;
font-size: 12px;
}
js
监听表单事件
// 导入请求接口文件
// <script type="module" src="./login.js"></script>
// import loginApi from "./loginApi.js";
// 获取页面元素
const account = document.querySelector('#username'); // 获取账号
const pwd = document.querySelector('#pwd'); // 获取密码框
const veriCode = document.querySelector('#veri_code'); // 获取验证码输入框
const veriCodeData = document.querySelector('#veri_code_img'); // 获取验证码数据
// const loginBtn = document.querySelector(".login-btn"); // 获取登录按钮
const tipBox = document.querySelector(".auto-tip-box"); // 获取提示框
const tipDesc = document.querySelector(".auto-tip-desc"); // 获取提示描述信息
// 页面加载完成 获取验证码信息
window.onload = function() {
loginApi("get","./code.png",true);
}
// 更改提示框描述文字
function updateTipText(ele,text) {
ele.innerText = text;
}
// 打开提示框
function openAlertTipBox(tipBoxEle,tipDescEle,text) {
tipBoxEle.style.display = "block";
// 更改提示框描述文字
updateTipText(tipDescEle,text);
}
// 关闭提示框
// 此处必须放在事件回调内
function closeAlertTipBox(ele,timer) {
if(ele.style.display === "block") {
// 提示框timer秒后隐藏
setTimeout(function() {
ele.style.display = "none";
},timer)
}
}
// 点击验证码
veriCodeData.addEventListener("click", function (e) {
console.log("zzzz");
loginApi("get","./code.png",true);
});
// 校验表单验证
function validateForm() {
console.log(account.value,'account.innerText')
if(!account.value) {
openAlertTipBox(tipBox,tipDesc,"账号不能为空");
closeAlertTipBox(tipBox,1000);
return false;
} else if (!pwd.value) {
openAlertTipBox(tipBox,tipDesc,"密码不能为空");
closeAlertTipBox(tipBox,1000);
return false;
} else if (!veriCode.value) {
openAlertTipBox(tipBox,tipDesc,"验证码不能为空");
closeAlertTipBox(tipBox,1000);
return false;
} else if (pwd.value && (pwd.value.trim().length < 5 || pwd.value.trim().length > 20)) {
openAlertTipBox(tipBox,tipDesc,"密码长度在5-20");
closeAlertTipBox(tipBox,1000);
return false;
}
}
// 阻止密码的粘贴
pwd.addEventListener("paste", function (e) {
e.preventDefault();
openAlertTipBox(tipBox,tipDesc,"禁止粘贴密码");
// 关闭提示框
closeAlertTipBox(tipBox,1000);
});
// 监听登录按钮的点击事件 无法阻止form的submit事件
// loginBtn.addEventListener("click", function (e) {
// let isValidatePass = validateForm();
// if(isValidatePass) {
// document.addForm.submit();
// }
// // 打开提示框
// // openAlertTipBox(tipBox,tipDesc,"用户名或者密码错误");
// // 如果登录失败
// // if(window.location.search.includes("error")) {
// // }
// // 关闭提示框
// // closeAlertTipBox(tipBox,1000);
// });
// 注意:
// onsubmit只能表单上form元素使用,提交表单前会触发,
封装的原生ajax
// export default
function loginApi(reqType, reqUrl, isAsync) {
let xhr;
if (window.XMLHttpRequest) {
// Firefox,Chrome,Opera,Safari
xhr = new XMLHttpRequest();
} else if (window.ActiveXObject) {
try {
// IE 7+
xhr = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
// IE 6-
xhr = new ActiveXObject("Microsoft.XMLHTTP");
} catch (err) {
console.log(err)
}
}
}
// 请求类型 路径 是否异步
xhr.open(reqType, reqUrl, isAsync);
// 向服务器发起请求
// 设置发送数据
xhr.send();
// 处理响应
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && xhr.status == 200) {
// responseText:获取字符串形式的响应数据
let resText = xhr.responseText;
// let resObj = JSON.parse(resText);
console.log(resText, 'resobj');
// 前端更新后台返回的验证码信息
document.querySelector('#veri_code_img').src = resText;
}
}
}
注意:如何触发提交表单之前的验证
- 不能直接监听类型为submit的登录按钮,这样是无法阻止submit的默认事件的,
- 1、可以使用form元素的onsubmit事件,
- 2、监听非submit类型的登录按钮的click事件,使用验证通过后,document.addForm.submit();