XTX实战案例
一、注册界面
1.获取短信验证码
- 添加点击事件
- if 判断控制事件的打开与关闭(防止短时间内多次获取)
- **重点:**flag变量的作用
<script>
// 1. 获取短信验证码
const code = document.querySelector('.code')
let flag = true // 通过变量控制点击事件
// 1.1 点击事件
code.addEventListener('click', function() {
if(flag) { // 当 flag为 true 可以进行点击事件
flag = false //关闭点击事件
let i = 5
code.innerHTML = `0${i}秒后重新获取`
let timerId = setInterval(function(){
i--
code.innerHTML = `0${i}秒后重新获取`
if(i === 0) {
clearInterval(timerId)
code.innerHTML = `重新获取`
flag = true // 打开点击事件
}
}, 1000)
}
})
</script>
2.用户名验证
- 判断时间:change事件,值发生变化时开始判断(开始执行函数)
1. 注意:封装函数,以便之后的使用 - 获取用户名输入框和输入框下提示字
- 正则表达式限定用户名输入
- 正则表达式判断——返回false后输入提示字
<script>
// 2. 用户名验证 (失去焦点后开始判断)
const username = document.querySelector('[name=username]')
// 2.1 使用 change事件 在值发生变化的时候进行正则判断
username.addEventListener('change', verifyName)
// 2.2 封装函数verifyName
function verifyName() {
// console.log(111)
// 获取下一个兄弟
const span = username.nextElementSibling
// 2.3定规则 (正则表达式)
const reg = /^[a-zA-Z0-9-_]{6,10}$/
if(!reg.test(username.value)){ // 2.4当正则表达式返回false时,执行下面函数
// console.log(111)
span.innerText = '输入不合法,请输入6-10位'
return false
}
// 2.5 正则表达式为true时,span内容清除
span.innerText = ''
return true
}
</script>
3.手机号验证
- 与2.同理
- 正则表达式为手机号验证的表达式
- 提示框文字变化
<script>
// 3. 手机号验证
// 3.1 获取手机表单
const phone = document.querySelector('[name=phone]')
phone.addEventListener('change', verifyPhone)
function verifyPhone() {
const span = phone.nextElementSibling
const reg = /^1(3\d|4[5-9]|5[0-35-9]|6[567]|7[0-8]|8\d|9[0-35-9])\d{8}$/
if(!reg.test(phone.value)){
span.innerText = '输入不合法,请输入正确的11位手机号码'
return false
}
span.innerText = ''
return true
}
</script>
4.验证码验证
- 与2.同理
- 正则表达式为验证码验证的表达式
- 提示框文字变化
<script>
// 4. 验证码验证
const codeInput = document.querySelector('[name=code]')
codeInput.addEventListener('change', verifyCode)
function verifyCode() {
const span = codeInput.nextElementSibling
const reg = /^\d{6}$/
if(!reg.test(codeInput.value)){
span.innerText = '输入错误,请输入正确的验证码'
return false
}
span.innerText = ''
return true
}
</script>
5.密码框验证
- 与2.同理
- 正则表达式为密码框验证表达式
- 提示文字变化
<script>
// 5. 验证密码框
const password = document.querySelector('[name=code]')
password.addEventListener('change', verifyPassword)
function verifyPassword() {
const span = password.nextElementSibling
const reg = /^\d{6}$/
if(!reg.test(password.value)){
span.innerText = '输入错误,请输入正确的验证码'
return false
}
span.innerText = ''
return true
}
</script>
6.再次输入密码验证
- 与2.类似
- if 判断输入与再次输入的值是否相同
- 再次输入密码不相同改变span的提示文字
- 相同返回true,span为空 (有错误,还未找到原因)
<script>
// 6. 密码的在此验证
const confirm = document.querySelector('[name=confirm]')
confirm.addEventListener('change', verifyConfirm)
function verifyConfirm() {
const span = confirm.nextElementSibling
// 6.1 如果两次密码输入不同,报错
if(confirm.value !== password.value){
span.innerText = '两次密码输入的不同'
console.log(111)
return false
}
span.innerText = ''
return true
}
</script>
7.同意协议模块
- this指向queren,控制类(CSS属性)的添加与删除,从而改变勾选*/*未勾选的状态
<script>
// 7. '我同意' 模块
const queren = document.querySelector('.icon-queren')
queren.addEventListener('click', function(){
// 切换类:有就删掉,没有就添加
this.classList.toggle('icon-queren2')
})
</script>
8.表单提交模块
- 阻止submit事件的页面跳转
- 查看是否勾选同意协议模块
1. 语法:元素.classList.contains('类名 ')
2. if 的反向判断 若为false弹出文字 - 判断上方2-6表单返回值是否都为true
<script>
// 8. 表单提交模块
const form = document.querySelector('form')
form.addEventListener('submit', function (e){
// 阻止页面跳转
e.preventDefault()
//语法:元素.classList.contains('类名') 查看是否包含此类
// 判断是否勾选了' 我同意' 模块 有——true,无——false
if(!queren.classList.contains('icon-queren2')){ //取反操作
return alert('请勾选同意协议')
}
// 判断上方的文本框是否通过,若没有则阻止
if(!verifyName()) e.preventDefault()
if(!verifyPhone()) e.preventDefault()
if(!verifyCode()) e.preventDefault()
if(!verifyPwd()) e.preventDefault()
if(!verifyConfirm()) e.preventDefault()
})
</script>
二、登录界面
1.Tap栏切换
- 获取两个pane(querySelectorAll获取两个同名pane)
- 点击事件(获取锚点a,获取后a大写为A)(e.target.tagName === ‘A’)
1. 事件监听:先取消后添加(active类)
2. if 循环显示对应模块(大盒子):先隐藏所有盒子,再显示点击的盒子
事件委托:
- 复杂的不适合事件委托
- 盒子与锚点为**父子关系(直接关系)**时,可以使用事件委托
<script>
// 1. Tap栏切换
// 复杂的不适合事件委托
// 盒子与锚点为父子关系时,可以使用事件委托
const tab_nav = document.querySelector('.tab-nav')
// 1.2 将两个 pane 获取过来
const pane = document.querySelectorAll('.tab-pane')
// 1.1 事件监听
tab_nav.addEventListener('click', function(e){
if (e.target.tagName === 'A'){
//取消上一个 active
tab_nav.querySelector('.active').classList.remove('active')
// 当前元素添加 active
e.target.classList.add('active')
// 1.3
// 先干掉所有人 —— for 循环
for(let i = 0;i < pane.length;i++){
pane[i].style.display = 'none'
}
// 让对应序号的 pane盒子 显示
pane[e.target.dataset.id].style.display = 'block'
}
})
</script>
2.点击提交模块
- 获取表单,获取登录按钮,获取用户名和密码
- 阻止submit的默认行为
- checked检查是否勾选协议:
1. if反向判断,若为 flase弹出提示框
<script>
// 2. 点击提交模块
const form = document.querySelector('form')
const agree = document.querySelector('[name=agree]')
const username = document.querySelector('[name=username]')
const password = document.querySelector('[name=password]')
form.addEventListener('submit', function(e){
// html5:input新增属性required --- 若为空提示
// 2.1 阻止默认行为
e.preventDefault()
// 2.2 checked 检查是否勾选协议
if(!agree.checked){ //没有勾选时执行
return alert('请勾选同意协议')
}
</script>
input新属性:
required —— 若为空弹出提示
3.将用户输入值存入本地存储
- **语法:**localStorage.setItem(‘key’,‘value’)来存储对应值
- 点击后跳转至主页
<script>
// 3. 记录用户名到本地存储
// 语法: localStorage.setltem('key','value')
// username为字符串 对象等复杂数据类型需用引号转为字符串
localStorage.setItem('xtx-uname',username.value)
localStorage.setItem('xtx-password',password.value)
// 跳转到首页
location.href = './index.html'
}) // —— 连接二.2的函数
</script>
三、账号登录后主页添加用户导航栏
1.登录后主页导航新添li
- 获取导航栏两个li
- 渲染函数(退出登录后使用)
1. 读取本地存储的用户名,对是否存在用户名进行判断
2. 如果存在则将用户名传入至用户导航栏(第一个li)
3. 将’免费注册’改为’退出登录’
<script>
// 账号登陆后,添加用户信息导航栏
// 1. 获取第一个 li
const li1 = document.querySelector('.xtx_navs li:first-child')
// 获取第二个 li
//语法:返回同一树级别中的下一个元素,不返回文本和注释节点
const li2 = li1.nextElementSibling
// 2. 渲染函数(退出后不用重新渲染)
function render() {
// 2.1 读取本地存储的用户名
const uname = localStorage.getItem('xtx-uname')
// console.log(uname)
// 2.2 对是否存在用户名进行判断
if (uname) {
li1.innerHTML = `<a href="javascript:;"><i class="iconfont icon-user">${uname}</i></a>`
// 2.3 将免费注册改为退出登录
li2.innerHTML = '<a href="./login.html">退出登录</a>'
}else{
li1.innerHTML = '<a href="./login.html">请先登录</a>'
li2.innerHTML = '<a href="./register.html">免费注册</a>'
}
}
render() // 调用函数
</script>
2.退出登录模块
- 退出登陆后,删除本地存储的数据
- 并且重新渲染函数
<script>
// 3. 点击退出登录模块
li2.addEventListener('click', function() {
// 删除本地存储的数据
localStorage.removeItem('xtx-uname')
localStorage.removeItem('xtx-password')
// 重新渲染
render()
})
</script>