实时校验输入框内容

<!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>
* {
margin: 0;
padding: 0;
}

.content {
margin: 50px auto;
}

button {
width: 100px;
height: 50px;
text-align: center;
line-height: 50px;
border: 1px solid black;
font-size: 30px;
}

.red {
background-color: red;
}

.gray {
background-color: gray;
}

input {
border: 1px solid black;
height: 50px;
font-size: 30px;
}

div {
margin-bottom: 20px;
text-align: center;
}

.error {
color: red;
}
</style>
</head>

<body>
<section class="content">
<div>
姓名:<input type="text" name="" id="name">
</div>
<div>
手机号: <input type="text" name="" id="phone">
</div>
<div>
分数:<input type="text" name="" id="score">
</div>
<div>
<button class="gray" id="btn">提交</button>
</div>
</section>

<script>
var nameEL = document.getElementById('name');
var phoneEL = document.getElementById('phone');
var scoreEL = document.getElementById('score');
var btn = document.getElementById('btn');

// 状态对象,包括输入选项的检查和整体状态的检查
var state = {
isOK: false, // 整体状态,提交按钮是否可点击
name: { // name 输入框的状态检查
check: function () {
return !!nameEL.value
},
errMsg: 'name 不能为空'
},
phone: { // phone 输入框的状态检查
check: function () {
var number = phoneEL.value;
var reg = /^[1][3,4,5,7,8][0-9]{9}$/;
return (!!number && reg.test(number))
},
errMsg: '手机号码不正确'
},
score: { // score 输入框的状态检查
check: function () {
return !!scoreEL.value
},
errMsg: 'score 不能为空'
},
// 整体状态检查函数
check: function () {
if (this.name.check() && this.phone.check() && this.score.check()) {
// 整体检验合格
this.isOK = true
// 按钮置为可用状态
btn.classList.remove('gray')
btn.classList.add('red')
} else {
// 整体检验不合格
this.isOK = false
// 按钮置为不可用状态
btn.classList.remove('red')
btn.classList.add('gray')
}
}
}

// name 元素监听 keyup 和 blur 事件
nameEL.addEventListener('keyup', debounce(function (event) {
tips.call(this, state.name)
state.check();
}, 500))
nameEL.addEventListener('blur', function (event) {
tips.call(this, state.name)
// 这里之所以不加 state.check, 是因为 keyup 时已经检查过了
})


// phone 元素监听 keyup 和 blur 事件
// keyup 事件,参数里的 500 是延迟校验的时间, 可调整
phoneEL.addEventListener('keyup', debounce(function (event) {
tips.call(this, state.phone)
state.check();
}, 500))
phoneEL.addEventListener('blur', function (event) {
tips.call(this, state.phone)
// 这里之所以不加 state.check, 是因为 keyup 时已经检查过了
})



// score 元素监听 keyup 和 blur 事件
scoreEL.addEventListener('keyup', debounce(function (event) {
tips.call(this, state.score)
state.check();
}, 500))
scoreEL.addEventListener('blur', function (event) {
tips.call(this, state.score)
// 这里之所以不加 state.check, 是因为 keyup 时已经检查过了
})

// 提交按钮点击事件
btn.addEventListener('click', function (event) {
if (!state.isOK) {
// 不可提交状态
var evt = document.createEvent('Event');
evt.initEvent('keyup', true, true);
// 触发三个输入框的 blur 事件
nameEL.dispatchEvent(evt)
phoneEL.dispatchEvent(evt)
scoreEL.dispatchEvent(evt)
} else {
// 可提交状态
console.log('submited')
}
})

// 错误提示信息处理函数
// obj 错误提示所属的元素
function tips(obj) {
var tipsEL = this.parentNode.querySelector('.error')
if (!obj.check()) {
if (!tipsEL) {
// 检验不通过 && 错误提示不存在
tipsEL = document.createElement('div')
tipsEL.innerHTML = obj.errMsg
tipsEL.classList.add('error')
this.parentNode.appendChild(tipsEL)
}
} else {
if (tipsEL) {
// 检验通过 && 错误提示已存在
this.parentNode.removeChild(tipsEL)
}
}
}

// 防抖函数,用于 keyup 事件优化性能
function debounce(fn, delay = 500) {
let timer = null;
return function (...rest) {
if (timer) {
clearTimeout(timer);
}
const self = this;
timer = setTimeout(function () {
fn.apply(self, rest);
timer = null;
}, delay);
};
}
</script>
</body>

</html>

猜你喜欢

转载自www.cnblogs.com/restart77/p/13376985.html