1. 正则表达式
1.1 基本使用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<!--
正则表达式(Regular Expression)是一种字符串匹配的模式(规则)
⚫ 使用场景:
➢ 例如验证表单:手机号表单要求用户只能输入11位的数字 (匹配)
➢ 过滤掉页面内容中的一些敏感词(替换),或从字符串中获取我们想要的特定部分(提取)
-->
<script>
// 1. 定义规则 其中/ /是正则表达式字面量;正则表达式也是对象
const reg1 = /JS/
const reg2 = new RegExp('JS')
let str1 = 'JS学习'
let str2 = 'TS学习'
let str3 = '学习'
// 2. 使用正则 test()方法 用来查看正则表达式与指定的字符串是否匹配,返回布尔型数据
console.log(reg1.test(str1)) // true
console.log(reg1.test(str2)) // false
console.log(reg1.test(str3)) // false
console.log(reg2.test(str1)) // true
console.log(reg2.test(str2)) // false
console.log(reg2.test(str3)) // false
</script>
</body>
</html>
1.2 元字符
1.2.1 边界符
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<!--
普通字符:普通字符只能够匹配字符串中与它们相同的字符
元字符(特殊字符):是一些具有特殊含义的字符,极大提高了灵活性和强大的匹配功能(边界符 量词 范围 字符类)
-->
<!--
边界符: 定义位置规则,必须用什么开头,用什么结尾
^ 开始 ; $ 结束 ; ^和$在一起,表示必须是精确匹配
-->
<script>
const reg1 = /JS/
const reg2 = /^JS/
const reg3 = /JS$/
const reg4 = /^JS$/
let str1 = 'JS学习'
let str2 = '学习JS'
let str3 = 'JS'
console.log(reg1.test(str1)) // true
console.log(reg2.test(str1)) // true
console.log(reg2.test(str2)) // false
console.log(reg3.test(str1)) // false
console.log(reg3.test(str2)) // true
console.log(reg4.test(str2)) // false
console.log(reg4.test(str3)) // true
</script>
</body>
</html>
1.2.2 量词
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<!-- 量词:用来设定某个模式重复次数 -->
<script>
// 有开始结束,精确匹配
// *:重复>=0 次
const reg1 = /^钱*$/
console.log(reg1.test('')) // t
console.log(reg1.test('钱')) // t
console.log(reg1.test('111')) // f
console.log('-------------------')
// +:重复>=1 次
const reg2 = /^钱+$/
console.log(reg2.test('')) // f
console.log(reg2.test('钱')) // t
console.log(reg2.test('钱钱')) // t
console.log('-------------------')
// ?:重复0次或1次
const reg3 = /^钱?$/
console.log(reg3.test('')) // t
console.log(reg3.test('钱')) // t
console.log(reg3.test('钱钱')) // f
console.log('-------------------')
// {n}:重复n次
const reg4 = /^钱{3}$/
console.log(reg4.test('钱钱')) // f
console.log(reg4.test('钱钱钱')) // t
console.log('-------------------')
// {n,}:重复>=n 次
const reg5 = /^钱{3,}$/
console.log(reg5.test('钱钱')) // f
console.log(reg5.test('钱钱钱')) // t
console.log(reg5.test('钱钱钱钱')) // t
console.log('-------------------')
// {n,m}:重复n~m 次(包含n,m) 逗号左右两侧千万不要出现空格
const reg6 = /^钱{3,5}$/
console.log(reg6.test('钱钱')) // f
console.log(reg6.test('钱钱钱')) // t
console.log(reg6.test('钱钱钱钱钱')) // t
</script>
</body>
</html>
1.2.3 范围
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<!--
范围:表示字符的范围,定义的规则限定在某个范围,
比如只能是英文字母,或者数字等等,用 [] 表示范围
[abc] 匹配包含的单个字符。也就是只有 a || b || c 这三个单字符返回true,可以理解为多选1
[a-z] 连字符。来指定字符范围。[a-z] 表示 a 到 z 26个英文字母
[^abc] 取反符。[^a-z] 匹配除了小写字母以外的字符
-->
<script>
// 单个字符
// 1. 多选1
const reg1 = /[abc]/
console.log(reg1.test('a')) // true
console.log(reg1.test('ac')) // true
console.log(reg1.test('cd')) // true
console.log(reg1.test('de')) // false
console.log('--------------')
// 2. 连字符
/*
➢ [a-z] 表示 a 到 z 26个英文字母都可以
➢ [a-zA-Z] 表示大小写都可以
➢ [0-9] 表示 0~9 的数字都可以
*/
const reg2 = /[a-f]/
console.log(reg2.test('a')) // true
console.log(reg2.test('ac')) // true
console.log(reg2.test('ch')) // true
console.log(reg2.test('hj')) // false
console.log('--------------')
// 3. 取反符
const reg3 = /[^abc]/
console.log(reg3.test('a')) // false
console.log(reg3.test('ac')) // false
console.log(reg3.test('cd')) // true
console.log(reg3.test('de')) // true
</script>
</body>
</html>
案例1_验证用户名
<!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>
<style>
dt,
dd {
margin: 0;
position: relative;
}
dl {
display: flex;
width: 600px;
height: 30px;
line-height: 30px;
}
dl dt {
margin-right: 5px;
}
dl input {
width: 269px;
height: 28px;
padding-left: 5px;
border: 1px solid #ccc;
outline: none;
background: transparent;
line-height: 30px;
border-radius: 5px;
}
.tip {
display: none;
position: relative;
width: 220px;
height: 30px;
margin-left: 15px;
border: 1px solid #f59fb1;
color: #d93c3c;
text-align: center;
font-size: 14px;
background-color: #fff2f5;
border-radius: 5px;
}
.tip::before {
content: '';
position: absolute;
top: 50%;
left: -6px;
width: 10px;
height: 10px;
background-color: #fff2f5;
border-left: 1px solid #f59fb1;
border-bottom: 1px solid #f59fb1;
transform: translateY(-50%) rotate(45deg);
}
span {
position: absolute;
top: 9px;
right: 10px;
width: 15px;
height: 15px;
}
.right {
background: url(./images/right.png) no-repeat;
}
.wrong {
background: url(./images/error1.png) no-repeat;
}
</style>
</head>
<body>
<dl>
<dt>用户名:</dt>
<dd><input type="text" class="uname"><span></span></dd>
<dd class="tip">输入6~16位数字字母-_组成</dd>
</dl>
<!--
用户名验证案例
需求:用户名要求用户英文字母,数字,下划线或者短横线组成,
并且用户名长度为 6~16 位 /^[a-zA-Z0-9_-]{6-16}$/
-->
<script>
const ipt = document.querySelector('.uname')
const rORw = document.querySelector('span')
const tip = document.querySelector('.tip')
/*
拓展补充:
➢ blur 事件:当元素失去焦点时触发(不论表单元素的值是否发生改变)
➢ change 事件:元素失去焦点并且表单元素的值发生改变才会触发
*/
const reg = /^[a-zA-Z0-9-_]{6,16}$/
ipt.addEventListener('change', function () {
if (reg.test(this.value)) {
/* rORw.classList.add('right')
rORw.classList.remove('wrong') */
// span只能有一个类名,right或wrong,直接className替换即可
rORw.className = 'right'
tip.style.display = 'none'
} else {
/* rORw.classList.remove('right')
rORw.classList.add('wrong') */
rORw.className = 'wrong'
tip.style.display = 'block'
}
})
</script>
</body>
</html>
1.2.4 字符类
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<!--
字符类:某些常见模式的简写方式,区分字母和数字
\d 匹配0-9之间的任一数字,相当于[0-9]
\D 匹配所有0-9以外的字符,相当于[^0-9]
\w 匹配任意的字母、数字和下划线,相当于[A-Za-z0-9_]
\W 除所有字母、数字和下划线以外的字符,相当于[^A-Za-z0-9_]
\s 匹配空格(包括换行符、制表符、空格符等),相等于[\t\r\n\v\f]
\S 匹配非空格的字符,相当于[^\t\r\n\v\f]
-->
<script>
// 日期格式(简易 不规范)
const reg = /^\d{4}-\d{1,2}-\d{1,2}$/
console.log(reg.test('2024-11-26')) // true
console.log(reg.test('2025-1-1')) // true
</script>
</body>
</html>
1.3 替换和修饰符
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<!--
替换和修饰符
replace 替换方法,可以完成字符的替换
字符串.replace(/正则表达式/, '替换的文本')
修饰符约束正则执行的某些细节行为,如是否区分大小写、是否支持多行匹配等
/表达式/修饰符
➢ i 是单词 ignore 的缩写,正则匹配时字母不区分大小写
➢ g 是单词 global 的缩写,匹配所有满足正则表达式的结果
-->
<script>
const str = '欢迎大家学习前端,相信大家一定能学好前端,都成为前端大神'
// 懒惰模式(默认),只匹配第一个,后面忽略
const newStr1 = str.replace(/前端/, '鸿蒙')
// replace 返回一个新的字符串,不修改原字符串
console.log(str) // 欢迎大家学习前端,相信大家一定能学好前端,都成为前端大神
console.log(newStr1) // 欢迎大家学习鸿蒙,相信大家一定能学好前端,都成为前端大神
// g 匹配所有满足正则表达式的结果
const newStr2 = str.replace(/前端/g, '鸿蒙')
console.log(newStr2) // 欢迎大家学习鸿蒙,相信大家一定能学好鸿蒙,都成为鸿蒙大神
</script>
</body>
</html>
案例2_隐藏手机号中间四位
<!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>
<style>
.wrapper {
width: 840px;
height: 420px;
background: url(./images/bg01.jpg) no-repeat center / cover;
padding: 100px 250px;
box-sizing: border-box;
}
.wrapper strong {
font-size: 50px;
}
.wrapper span {
color: #b10e0d;
}
</style>
</head>
<body>
<div class="wrapper">
<strong>年会抽奖</strong>
<h1>获奖手机号:<span class="phone">???</span></h1>
</div>
<!-- 隐藏手机号中间四位案例 -->
<script>
let tel = '13866668888'
// 把手机号利用正则利用小括号划分为三部分
const reg = /^(\d{3})(\d{4})(\d{4})$/
// 在replace中,$1 对应第一个小括号内容,依次类推
let str1 = tel.replace(reg, '$1****$3')
// ${} -- 模板字符串${变量或表达式}
// 字符串重复使用:字符串.repeat(次数) 实现
let str2 = tel.replace(reg, `$1${'*'.repeat(4)}$3`)
document.querySelector('.phone').innerHTML = str1
</script>
</body>
</html>
2. JS插件
2.1 AlloyFinger 手势插件
<!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>AlloyFinger手势插件</title>
<style>
.nav {
width: 200px;
height: 40px;
border: 3px solid pink;
}
.item {
width: 250px;
height: 40px;
line-height: 40px;
background-color: skyblue;
transition: all .3s;
}
.active {
transform: translateX(-50px);
}
</style>
</head>
<body>
<div class="nav">
<div class="item">
AlloyFinger是腾讯AlloyTeam 开发
</div>
</div>
<!-- AlloyFinger 是腾讯 AlloyTeam 团队开源的超轻量级 Web 手势插件,为元素注册各种手势事件 -->
<!-- 将AlloyFinger库引入当前文件 -->
<!--
配置
new AlloyFinger(element, { // element 是给哪个元素做滑动事件
swipe: function (e) {
// 滑动的时候要做的事情 e.direction 可以判断上下左右滑动 Left Right 等
}
})
-->
<script src="./alloy_finger.js"></script>
<script>
const item = document.querySelector('.item')
new AlloyFinger(item, {
swipe: function (e) {
if (e.direction === 'Left') {
item.classList.add('active')
} else if (e.direction === 'Right') {
item.classList.remove('active')
}
},
// 手指触摸
touchStart: function () {
console.log('touchStart')
},
// 手指移动
touchMove: function () {
console.log('touchMove')
},
// 手指移开
touchEnd: function () {
console.log('touchEnd')
}
})
</script>
</body>
</html>
2.2 M端事件
<!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>
.box {
width: 300px;
height: 300px;
background-color: pink;
}
</style>
</head>
<body>
<div class="box"></div>
<!--
M端(移动端)有自己独特的地方。比如触屏事件 touch(也称触摸事件)。
touch 对象代表一个触摸点。触摸点可能是一根手指,也可能是一根触摸笔。
触屏事件可响应用户手指(或触控笔)对屏幕或者触控板操作。
触屏touch事件
touchstart 手指触摸到一个DOM元素时触发
touchmove 手指在一个DOM元素上滑动时触发
touchend 手指从一个DOM元素上移开时触发
-->
<script>
const box = document.querySelector('.box')
box.addEventListener('touchstart', function () {
console.log('touchstart')
})
box.addEventListener('touchmove', function () {
console.log('touchmove')
})
box.addEventListener('touchend', function () {
console.log('touchend')
})
</script>
</body>
</html>
2.3 a11y-dialog 对话框插件
<body>
<!-- 按钮 -->
<div class="btns">
<button class="btn btn1">添加</button>
</div>
<!-- a11y -->
<!-- 1. 准备对话框容器 -->
<div class="dialog-container" id="dialog" aria-hidden="true">
<!-- 2. 底部蒙层 -->
<div class="dialog-overlay" data-a11y-dialog-hide></div>
<!-- 3. 对话框结构 -->
<div class="dialog-content">
<!-- 4. 关闭按钮 -->
<button type="button" class="dialog-close" data-a11y-dialog-hide>
×
</button>
<!-- 5. 标题 -->
<h1>测试对话框</h1>
<!-- 6. 内容 -->
<p>好看的对话框</p>
</div>
</div>
<!-- <script src="https://cdn.jsdelivr.net/npm/a11y-dialog@8/dist/a11y-dialog.min.js"></script> -->
<script src="./a11y-dialog.js"></script>
<script>
const btn1 = document.querySelector('.btn1')
// 获取对话框DOM容器
const element = document.querySelector('#dialog')
// 实例化对话框
const dialog = new A11yDialog(element)
btn1.addEventListener('click', function () {
// 实例对话框调用 show 方法可以显示对话框
dialog.show()
})
</script>
</body>
3. 字符串截取
<script>
const str = '我们都是前端大神啊'
// 字符串截取
// 1. substring
// 最后一个字符
console.log(str.substring(str.length - 1)) // 啊
// 第一个字符
console.log(str.substring(0, 1)) // 我
// 2. str[] 字符串也有索引,
console.log(str[0]) // 我
</script>
4. 综合案例_移动端通讯录