当前位置: 首页 > news >正文

十二、正则表达式、元字符、替换修饰符、手势和对话框插件、字符串截取

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)) // trueconsole.log(reg1.test(str2)) // falseconsole.log(reg1.test(str3)) // falseconsole.log(reg2.test(str1)) // trueconsole.log(reg2.test(str2)) // falseconsole.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)) // trueconsole.log(reg2.test(str1)) // trueconsole.log(reg2.test(str2)) // falseconsole.log(reg3.test(str1)) // falseconsole.log(reg3.test(str2)) // trueconsole.log(reg4.test(str2)) // falseconsole.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('')) // tconsole.log(reg1.test('钱')) // tconsole.log(reg1.test('111')) // fconsole.log('-------------------')// +:重复>=1 次const reg2 = /^钱+$/console.log(reg2.test('')) // fconsole.log(reg2.test('钱')) // tconsole.log(reg2.test('钱钱')) // tconsole.log('-------------------')// ?:重复0次或1次const reg3 = /^钱?$/console.log(reg3.test('')) // tconsole.log(reg3.test('钱')) // tconsole.log(reg3.test('钱钱')) // fconsole.log('-------------------')// {n}:重复n次const reg4 = /^钱{3}$/console.log(reg4.test('钱钱')) // fconsole.log(reg4.test('钱钱钱')) // tconsole.log('-------------------')// {n,}:重复>=n 次const reg5 = /^钱{3,}$/console.log(reg5.test('钱钱')) // fconsole.log(reg5.test('钱钱钱')) // tconsole.log(reg5.test('钱钱钱钱')) // tconsole.log('-------------------')// {n,m}:重复n~m 次(包含n,m) 逗号左右两侧千万不要出现空格const reg6 = /^钱{3,5}$/console.log(reg6.test('钱钱')) // fconsole.log(reg6.test('钱钱钱')) // tconsole.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. 多选1const reg1 = /[abc]/console.log(reg1.test('a')) // trueconsole.log(reg1.test('ac')) // trueconsole.log(reg1.test('cd')) // trueconsole.log(reg1.test('de')) // falseconsole.log('--------------')// 2. 连字符/* ➢ [a-z] 表示 a 到 z 26个英文字母都可以➢ [a-zA-Z] 表示大小写都可以➢ [0-9] 表示 0~9 的数字都可以*/const reg2 = /[a-f]/console.log(reg2.test('a')) // trueconsole.log(reg2.test('ac')) // trueconsole.log(reg2.test('ch')) // trueconsole.log(reg2.test('hj')) // falseconsole.log('--------------')// 3. 取反符const reg3 = /[^abc]/console.log(reg3.test('a')) // falseconsole.log(reg3.test('ac')) // falseconsole.log(reg3.test('cd')) // trueconsole.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')) // trueconsole.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>&times;</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. 综合案例_移动端通讯录

<!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="./iconfont/iconfont.css" /><link rel="stylesheet" href="./index.css" />
</head><body><div class="address-header">通讯录<i class="iconfont icon-tianjiayonghu"></i></div><div class="address-book"><!-- 添加item 核心区域--><!-- <div class="item"><p class="circle">华</p><p class="name">刘德华</p><p class="tel">15300588305</p><a class="del" href="javascript:;"><i class="iconfont icon-shanchutianchong" data-index="0"></i></a></div> --></div><button id="add" class="btn-add">添加联系人</button><!-- 模态框-添加联系人 --><div class="dialog-container" id="modal" aria-hidden="true" aria-labelledby="my-dialog-title"aria-describedby="my-dialog-description"><div class="dialog-overlay" data-a11y-dialog-hide></div><div class="dialog-content" role="document"><h1 id="my-dialog-title" class="title">添加联系人<button type="button" aria-label="Close this dialog window" class="el-dialog__headerbtn dialog-close"data-a11y-dialog-hide>取消</button></h1><!-- 联系人表单 --><div class="address-footer"><input id="name" type="text" placeholder="请输入姓名" /><input id="tel" type="text" placeholder="请输入手机号" /><button class="btn-ok" id="btnOK">确认</button></div></div></div><!-- 引入手势插件 --><script src="./js/alloy_finger.js"></script><!-- 引入弹窗插件 --><script src="./js/a11y-dialog.js"></script><script>// 本地存储let arr = JSON.parse(localStorage.getItem('contacts')) || []// 初始化数据/* let arr = [{ name: '周杰伦', tel: '13411112222' },{ name: '刘德华', tel: '13511112222' },{ name: '张学友', tel: '13711112222' },{ name: '岳云鹏', tel: '13911112222' },{ name: '迪丽热巴', tel: '13911112222' }] */const addressBook = document.querySelector('.address-book')// 渲染业务function render(data = arr) {let str = data.map((item, index) => {const { name, tel } = itemreturn `<div class="item"><p class="circle">${name.substring(name.length - 1)}</p><p class="name">${name}</p><p class="tel">${tel}</p><a class="del" href="javascript:;"><i class="iconfont icon-shanchutianchong" data-index="${index}"></i></a></div>`}).join('')addressBook.innerHTML = str/* 调用滑动功能每次 render 函数被调用后都会被执行,确保对新生成的 .item 元素进行了正确的事件绑定。 */swipe()}render()// 滑动业务// 滑动业务事件委托做不了,e.target值不确定 p div? --> forEach做// 要在渲染的时候准备好滑动功能等待用户滑动 -- 定义滑动函数,渲染函数中调用function swipe() {// forEach 遍历添加事件监听// 获取items元素若放到顶部,此时render函数未调用,HTML未填充item元素,获取元素失败 --> 滑动功能实现失败const items = document.querySelectorAll('.address-book .item')items.forEach(item => {new AlloyFinger(item, {swipe: function (e) {// console.log(e)if (e.direction === 'Left') {// 排他// 1. 页面打开默认有自带active类名,下行代码可行;默认无active找不到元素返回为空,控制台classList报错// document.querySelector('.address-book .active').classList.remove('active')// 2. css选择器书写错误 item和active同级类名,找不到item下的active符合条件的元素// document.querySelector('.item .active')?.classList.remove('active')const active = document.querySelector('.address-book .active')// 3.1 正确写法一 if判断/* if (active) {active.classList.remove('active')} */// 3.2 正确写法二 ?可选// active?.classList.remove('active')// 3.3 正确写法三 逻辑中断active && active.classList.remove('active')item.classList.add('active')} else if (e.direction === 'Right') {item.classList.remove('active')}}})})}// 删除业务 事件委托addressBook.addEventListener('click', function (e) {// console.log(e.target.dataset.index)if (e.target.classList.contains('icon-shanchutianchong')) {// confirm() 弹窗 返回值为布尔型let isDel = confirm('确定要删除嘛?')if (isDel) {arr.splice(e.target.dataset.index, 1)localStorage.setItem('contacts', JSON.stringify(arr))render()} else {document.querySelector('.active').classList.remove('active')}}})// 新增业务const btnAdd = document.querySelector('.btn-add')// 获取对话框DOM容器const modal = document.querySelector('#modal')// 实例化对话框const dialog = new A11yDialog(modal)btnAdd.addEventListener('click', function () {dialog.show()})const btnOK = document.querySelector('#btnOK')const uname = document.querySelector('#name')const tel = document.querySelector('#tel')btnOK.addEventListener('click', function () {// 验证数据合法?let unameReg = /^(?:[\u4e00-\u9fa5·]{2,16})$/let telReg = /^(?:(?:\+|00)86)?1[3-9]\d{9}$/let addName = uname.valuelet addTel = tel.valueif (!addName.trim() || !addTel.trim()) {alert('不能为空')return}if (!unameReg.test(addName)) {alert('姓名输入错误')return}if (!telReg.test(addTel)) {alert('电话输入错误')return}arr.unshift({ name: addName, tel: addTel })localStorage.setItem('contacts', JSON.stringify(arr))render()// 关闭添加联系人页面dialog.hide()uname.value = ''tel.value = ''})</script>
</body></html>

5. 作业

5.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><link rel="stylesheet" href="index.css"></head><body><header><h1><img src="https://bm.ruankao.org.cn/asset/image/public/logo.png" alt=""><span>全国计算机技术与软件专业技术资格(水平)考试</span><span class="address">当前考区:北京</span></h1><div><span class="hello">xxx,您好!</span></div></header><main><section><h3>基本信息</h3><form action="#"><div class="form-item is-required"><label for="username">姓名:</label><div class="form-item-content"><input class="hm-input" type="text" id="username"><!-- <div class="form-error hide">用户名校验不通过,请输入1-4位的汉字</div> --><div class="form-error">用户名校验不通过,请输入1-4位的汉字</div></div></div><div class="form-item is-required"><label for="idcard">身份证:</label><div class="form-item-content"><input class="hm-input" type="text" id="idcard"><!-- <div class="form-error hide">请输入合法的身份证格式</div> --><div class="form-error">请输入合法的身份证格式</div></div></div><div class="form-item is-required"><label for="age">年龄:</label><div class="form-item-content"><input class="hm-input" type="text" id="age"><!-- <div class="form-error hide">请输入数字</div> --><div class="form-error">请输入数字</div></div></div><div class="form-item is-required"><label for="mobile">手机号:</label><div class="form-item-content"><input class="hm-input" type="text" id="mobile"><!-- <div class="form-error hide">请输入合法的手机号</div> --><div class="form-error">请输入合法的手机号</div></div></div><button class="submit">提交</button></form></section></main><!-- 需求如下:点击提交时,对表单进行数据格式校验:校验不通过,显示错误提示校验通过,跳转到成功页面--><script>const form = document.querySelector('form')const username = document.querySelector('#username')const idcard = document.querySelector('#idcard')const age = document.querySelector('#age')const mobile = document.querySelector('#mobile')// 正则const regUsername = /^(?:[\u4e00-\u9fa5]{1,4})$/const regIdcard = /^\d{6}((((((19|20)\d{2})(0[13-9]|1[012])(0[1-9]|[12]\d|30))|(((19|20)\d{2})(0[13578]|1[02])31)|((19|20)\d{2})02(0[1-9]|1\d|2[0-8])|((((19|20)([13579][26]|[2468][048]|0[48]))|(2000))0229))\d{3})|((((\d{2})(0[13-9]|1[012])(0[1-9]|[12]\d|30))|((\d{2})(0[13578]|1[02])31)|((\d{2})02(0[1-9]|1\d|2[0-8]))|(([13579][26]|[2468][048]|0[048])0229))\d{2}))(\d|X|x)$/const regAge = /^\d{1,2}$/const regMobile = /^(?:(?:\+|00)86)?1(?:(?:3[\d])|(?:4[5-79])|(?:5[0-35-9])|(?:6[5-7])|(?:7[0-8])|(?:8[\d])|(?:9[1589]))\d{8}$/function REG(reg, el) {return reg.test(el.trim())}/* console.log(REG(regUsername, '小红')) // tconsole.log(REG(regUsername, '红')) // tconsole.log(REG(regUsername, '12352')) // f */form.addEventListener('submit', function (e) {if (REG(regUsername, username.value)) {// nextElementSibling 获取节点的下一个兄弟节点username.nextElementSibling.classList.add('hide')}if (REG(regIdcard, idcard.value)) {idcard.nextElementSibling.classList.add('hide')}if (REG(regAge, age.value)) {age.nextElementSibling.classList.add('hide')}if (REG(regMobile, mobile.value)) {mobile.nextElementSibling.classList.add('hide')}// console.log(document.querySelectorAll('.hide'))// console.log(document.querySelectorAll('.hide').length) // '4'// console.log(document.querySelectorAll('.hide').length == '4')// 阻止表单默认行为e.preventDefault()if (document.querySelectorAll('.hide').length == '4') {// console.log('success')location.href = './success.html'}})</script>
</body></html>

5.2 仿outlook邮箱

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><link rel="stylesheet" href="./index.css"><link rel="stylesheet" href="./fonts/iconfont.css">
</head><body><header><span class="iconfont icon-hanbaobao"></span><span>收件箱</span><img src="./imgs/default-avatar.png" alt=""></header><ul class="mail-list"><!-- <li class="unread"><div class="group"><div class="status">标记已读</div><article><img src="./imgs/default-avatar.png" alt=""><div class="mail-info"><div><span class="from">Jack</span><time>2023/10/1</time></div><p>您好, 您之所以会收到此邮件,是因为我们正在更新 Microsoft 服务协议,该协议适用于您所使用的一个或多个 Microsoft产品或服务。我们之所以进行这些更新,是为了阐明我们的条款并确保这些条款仍对您保持透明。</p></div></article></div></li> --></ul><!-- <script src="https://unpkg.com/alloyfinger@0.1.16/alloy_finger.js"></script> --><script src="../alloy_finger.js"></script><script src="data.js"></script><script>const list = document.querySelector(".mail-list")function render(data = mails) {let str = data.map((el, index) => {const {from: { username, avatar },time,content,readStatus,} = elreturn `<li class="unread"><div class="group"><div class="status">标记已读</div><article><img src="${avatar}" alt=""><div class="mail-info"><div><span class="from">${username}</span><time>${time}</time></div><p>${content}/p></div></article></div></li>`}).join("")list.innerHTML = strswipefn()}render()// 滑动发生时 内容内标签变化 需再次渲染可实现滑动 封装滑动功能函数 渲染函数内调用function swipefn() {// 新增需求:向右滑动,出现操作区块,点击可修改邮件的阅读状态const lis = document.querySelectorAll(".mail-list li")// previousElementSibling 上一个兄弟节点lis.forEach((item) => {console.log(item.tagName) // LI// 查找子节点的子节点const status = item.children[0].children[0]// console.log(status)new AlloyFinger(item, {// swipe: function (e) {// console.log(e.target)if (e.direction === "Right") {item.classList.toggle('active')item.classList.contains('read')? status.innerHTML = '标记未读': status.innerHTML = '标记已读'}},touchStart: function (e) {if (e.target.classList.contains('status')) {item.classList.toggle('active')item.classList.toggle('read')status.innerHTML = '标记未读'}}})})}</script>
</body></html>

相关文章:

十二、正则表达式、元字符、替换修饰符、手势和对话框插件、字符串截取

1. 正则表达式 1.1 基本使用 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</title&g…...

嵌入式的应用领域有哪些

首先给大家介绍一下‌‌&#xff0c;STM32是‌意法半导体&#xff08;STMicroelectronics&#xff09;生产的32位微控制器&#xff08;‌MCU&#xff09;系列‌&#xff0c;采用‌ARM Cortex-M内核设计&#xff0c;以其高性能、低功耗和广泛的应用而闻名。‌ 那么意法半导体是在…...

git merge :开发分支与主分支的交互

一、开发分支&#xff08;dev&#xff09;上的代码达到上线的标准后&#xff0c;要合并到 master 分支 git checkout dev git pull git checkout master git merge dev git push -u origin master 二、当master代码改动了&#xff0c;需要更新开发分支&#xff08;dev&#x…...

OGRE 3D----4. OGRE和QML共享opengl上下文

在现代图形应用开发中,OGRE(Object-Oriented Graphics Rendering Engine)和QML(Qt Modeling Language)都是非常流行的工具。OGRE提供了强大的3D渲染能力,而QML则用于构建灵活的用户界面。在某些应用场景中,我们需要在同一个应用程序中同时使用OGRE和QML,并且共享OpenGL…...

ArcGIS 软件中路网数据的制作

内容导读 路网数据是进行网络分析的基础&#xff0c;它是建立网络数据集的数据来源。 本文我们以OSM路网数据为例&#xff0c;详细介绍OSM路网数据从下载&#xff0c;到数据处理&#xff0c;添加属性&#xff0c;完成符合网络分析的网络数据集的全部过程。 01 数据获取 比较…...

Milvus 2.5:全文检索上线,标量过滤提速,易用性再突破!

01. 概览 我们很高兴为大家带来 Milvus 2.5 最新版本的介绍。 在 Milvus 2.5 里&#xff0c;最重要的一个更新是我们带来了“全新”的全文检索能力&#xff0c;之所以说“全新”主要是基于以下两点&#xff1a; 第一&#xff0c;对于全文检索基于的 BM25 算法&#xff0c;我们采…...

Windows常用DOS指令(附案例)

文章目录 1.dir 查看当前目录2.cd 进入指定目录3.md 创建指定目录4.cd> 创建指定文件5.rd 删除指定空目录6.del 删除指定文件7.copy 复制文件8.xcopy 批量复制9.ren 改名10.type 在命令行空窗口打开文件11.cls 清空DOS命令窗口12.chkdsk 检查磁盘使用情况13.time 显示和设置…...

搜索二维矩阵 II(java)

题目描述 编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target 。该矩阵具有以下特性&#xff1a; 每行的元素从左到右升序排列。每列的元素从上到下升序排列。 代码思路&#xff1a; 用暴力算法&#xff1a; class Solution {public boolean searchMatrix(…...

Webpack 的构建流程

Webpack 的构建流程可以概括为以下几个步骤&#xff1a; 1. 初始化&#xff1a; Webpack 读取配置文件&#xff08;webpack.config.js&#xff09;&#xff0c;合并默认配置和命令行参数&#xff0c;初始化Compiler对象。 2. 构建依赖图&#xff1a; 从入口文件开始递归地分…...

Kylin Server V10 下 RocketMQ 主备自动切换模式部署

一、NameServer简介 NameServer 是一个注册中心,提供服务注册和服务发现的功能。NameServer 可以集群部署,集群中每个节点都是对等的关系,节点之间互不通信。 服务注册 Broker 启动的时候会向所有的 NameServer 节点进行注册,注意这里是向集群中所有的 NameServer 节点注册…...

Linux启动中出现“psi: inconsistent task state!”错误可能原因

在Linux系统中&#xff0c;psi: inconsistent task state! 异常日志通常与 PSI&#xff08;Pressure Stall Information&#xff09;相关。PSI 是 Linux 内核中的一个特性&#xff0c;用于监控系统资源的压力情况&#xff0c;如 CPU、内存和 I/O 等。该日志信息表明在处理任务状…...

FCBP 认证考试要点摘要

理论知识 数据处理与分析&#xff1a;包括数据的收集、清洗、转换、存储等基础操作&#xff0c;以及数据分析方法&#xff0c;如描述性统计分析、相关性分析、数据挖掘算法等的理解和应用 。数据可视化&#xff1a;涉及图表类型的选择与应用&#xff0c;如柱状图、折线图、饼图…...

ubuntu防火墙入门(一)——设置服务、关闭端口

本机想通过git clone gitgithub.com:skumra/robotic-grasping.git下载代码&#xff0c;firewall-config中需要为当前区域的防火墙开启SSH服务吗 是的&#xff0c;如果你想通过 git clone gitgithub.com:skumra/robotic-grasping.git 使用 SSH 协议从 GitHub 下载代码&#xff0…...

yt6801 ubuntu有线连接驱动安装

耀世16pro的有线网卡驱动安装 下载地址: YT6801 千兆PCIE以太网控制器芯片 1. 创建安装目录 mkdir yt68012. 解压驱动文件 unzip yt6801-linux-driver-1.0.27.zip -d yt68013. 进入驱动目录 cd yt68014. 安装驱动 以 root 权限运行安装脚本&#xff1a; sudo su ./yt_ni…...

ASP.NET Core Web API 控制器

文章目录 一、基类&#xff1a;ControllerBase二、API 控制器类属性三、使用 Get() 方法提供天气预报结果 在深入探讨如何编写自己的 PizzaController 类之前&#xff0c;让我们先看一下 WeatherController 示例中的代码&#xff0c;了解它的工作原理。 在本单元中&#xff0c;…...

【论文笔记】Tool Learning with Foundation Models 论文笔记

Tool Learning with Foundation Models 论文笔记 文章目录 Tool Learning with Foundation Models 论文笔记摘要背景&#xff1a;工作&#xff1a; 引言工具学习的发展本文工作&#xff08;大纲&目录&#xff09; 背景2.1 工具使用的认知起源2.2 工具分类&#xff1a;用户界…...

STM32 + CubeMX + 串口 + IAP升级

这篇文章分享一个简单的串口IAP Demo&#xff0c;实现使用串口更新我们自己的App程序。 目录 一、IAP简介二、Stm32CubeMx配置三、Boot代码及配置1、代码2、配置 四、App代码及配置1、代码2、配置 五、效果展示 一、IAP简介 IAP介绍可以在网上找找&#xff0c;相关资料很多&am…...

Oracle-—系统包使用

文章目录 系统包dbms_redefinition 系统包 dbms_redefinition 功能介绍&#xff1a;该包体可以实现将Oracle库下的表在线改为分区结构或者重新定义&#xff1b; 说明&#xff1a;在检查表是否可以重定义和开始重定义的过程中&#xff0c;按照表是否存在主键&#xff0c;参数 o…...

使用Hugo和GitHub Pages创建静态网站个人博客

不需要服务器&#xff0c;不需要域名&#xff0c;不需要数据库&#xff0c;可以选择模版&#xff0c;内容为Markdown格式。 Hugo&#xff1a;https://gohugo.io 文档&#xff1a;https://gohugo.io/getting-started/quick-start/ 中文文档&#xff1a;https://www.gohugo.or…...

群晖系统证书延期

群晖系统默认证书过期了 接下来操作续期证书 一直下一步会让下载一个压缩包里面包含私钥和签发证书请求 下载后解压出来 在群晖里用证书续期 对以前的证书签署签发请求 选择刚刚解压出来的证书 执行完成后会下载一个压缩包&#xff0c;解压出来就会得到新证书 给群晖新增证书 选…...

android shader gl_Position是几个分量

在Android的OpenGL ES中&#xff0c;gl_Position是顶点着色器&#xff08;Vertex Shader&#xff09;的一个内置输出变量&#xff0c;它用于指定顶点在裁剪空间&#xff08;Clip Space&#xff09;中的位置。gl_Position是一个四维向量&#xff08;4-component vector&#xff…...

JAVA练习-ArrayList数组

需求 建立3个Student类的实例 原始数组&#xff1a; public class Student {private String name;private int score;public Student(String name, int score) {this.name name;this.score score;}Overridepublic String toString() {return name "的分数&#xff1…...

springboot339javaweb的新能源充电系统pf(论文+源码)_kaic

毕 业 设 计&#xff08;论 文&#xff09; 题目&#xff1a;新能源充电系统的设计与实现 摘 要 如今社会上各行各业&#xff0c;都喜欢用自己行业的专属软件工作&#xff0c;互联网发展到这个时候&#xff0c;人们已经发现离不开了互联网。新技术的产生&#xff0c;往往能解…...

数据结构——排序第三幕(深究快排(非递归实现)、快排的优化、内省排序,排序总结)超详细!!!!

文章目录 前言一、非递归实现快排二、快排的优化版本三、内省排序四、排序算法复杂度以及稳定性的分析总结 前言 继上一篇博客基于递归的方式学习了快速排序和归并排序 今天我们来深究快速排序&#xff0c;使用栈的数据结构非递归实现快排&#xff0c;优化快排&#xff08;三路…...

Jackson:Java对象和JSON字符串的转换处理库使用指南

Jackson介绍 Jackson 是一个非常流行的 Java JSON 处理库&#xff0c;它能够将 Java 对象与 JSON 字符串相互转换。 Jackson 工具主要用于将请求的参数&#xff08;例如前端发送的 JSON 数据&#xff09;和响应的数据&#xff08;例如后端返回给前端的数据&#xff09;转换成…...

mac maven编译出现问题

背景 进行maven install 命令&#xff0c;报错&#xff1a; [ERROR] COMPILATION ERROR : [INFO] ------------------------------------------------------------- [ERROR] No compiler is provided in this environment. Perhaps you are running on a JRE rather than a J…...

深入讲解Spring Boot和Spring Cloud,外加图书管理系统实战!

很抱歉&#xff0c;我的疏忽&#xff0c;说了这么久还没有给大家详细讲解过Spring Boot和Spring Cloud,那今天给大家详细讲解一下。 大家可以和下面这三篇博客一起看&#xff1a; 1、Spring Boot 和 Spring Cloud 微服务开发实践详解https://blog.csdn.net/speaking_me/artic…...

【AIGC】2023-ICCV-用于高保真语音肖像合成的高效区域感知神经辐射场

2023-ICCV-Efficient Region-Aware Neural Radiance Fields for High-Fidelity Talking Portrait Synthesis 用于高保真语音肖像合成的高效区域感知神经辐射场摘要1. 引言2. 相关工作3. 方法3.1 准备工作和问题设置3.2 三平面哈希表示3.3. 区域注意模块3.4 训练细节 4. 实验4.1…...

如何写一份优质技术文档

作者简介&#xff1a; 本文作者拥有区块链创新专利30&#xff0c;是元宇宙标准化工作组成员、香港web3标准工作组成员&#xff0c;参与编写《数据资产确权与交易安全评价标准》、《链接元宇宙&#xff1a;应用与实践》、《香港Web3.0标准化白皮书》等标准&#xff0c;下面提供…...

ML 系列:第 35 节 - 机器学习中的数据可视化

ML 系列&#xff1a;第 35 天 - 机器学习中的数据可视化 文章目录 一、说明二、数据可视化2.1 直方图2.2 箱线图2.3 散点图2.4 条形图2.5 线图2.6 热图 三、结尾 一、说明 描述性统计和数据可视化是理解和解释机器学习数据的基础。它们有助于总结和直观地呈现数据&#xff0c…...

存储服务器一般做是做什么阵列?详细列举一下

存储服务器通常使用 RAID&#xff08;Redundant Array of Independent Disks&#xff09; 阵列技术来管理磁盘&#xff0c;以提高数据的性能、可靠性和可用性。所选择的 RAID 类型取决于存储服务器的具体用途和需求&#xff0c;比如性能要求、容量需求、容错能力等。 以下是存…...

uniapp使用扩展组件uni-data-select出现的问题汇总

前言 不知道大家有没有学习过我的这门课程那&#xff0c;《uniCloud云开发Vue3版本官方推荐用法》&#xff0c;这么课程已经得到了官方推荐&#xff0c;想要快速上手unicloud的小伙伴们&#xff0c;可以学习一下这么课程哦&#xff0c;不要忘了给一键三连呀。 在录制这门课程…...

pdf.js 预览pdf的时候发票数据缺失显示不全:字体加载出错(缺失)导致部分缺失

首先&#xff0c;排除后端返回的PDF文件流是没有问题的&#xff1a; 但是在vue项目中是这样的&#xff1a; 明显是显示不全&#xff0c;F12查看报错信息&#xff0c;有以下警告&#xff1a; pdf.js:2153 Warning: Error during font loading: The CMap “baseUrl” paramet…...

【设计模式】【结构型模式(Structural Patterns)】之外观模式(Facade Pattern)

1. 设计模式原理说明 外观模式&#xff08;Facade Pattern&#xff09; 是一种结构型设计模式&#xff0c;它提供了一个统一的接口&#xff0c;用来访问子系统中的一群接口。外观模式定义了一个高层接口&#xff0c;这个接口使得这一子系统更加容易使用。通过隐藏子系统的复杂…...

Redis使用场景-缓存-缓存穿透

前言 之前在针对实习面试的博文中讲到Redis在实际开发中的生产问题&#xff0c;其中缓存穿透、击穿、雪崩在面试中问的最频繁&#xff0c;本文加了图解&#xff0c;希望帮助你更直观的了解缓存穿透&#x1f600; &#xff08;放出之前写的针对实习面试的关于Redis生产问题的博…...

介绍 Apache Spark 的基本概念和在大数据分析中的应用

Apache Spark 是一个开源的大数据处理框架&#xff0c;它提供了快速、通用、可扩展的数据处理能力。Spark可以处理大规模数据集&#xff0c;并且在内存中进行数据操作&#xff0c;从而实现高速的数据处理和分析。 Spark的核心概念是弹性分布式数据集&#xff08;Resilient Dis…...

OpenCPN-插件之Dashboard Tactics

1&#xff1a;相关链接Dashboard Tactics :: OpenCPN Dashboard Tactics Plugin rgleason/dashboard_tactics_pi: OpenCPN dashboard built-in plugin merger with external tactics_pi plugin NMEAconverter :: OpenCPN 2&#xff1a;显示样式 3&#xff1a;代码 这个插件…...

【LeetCode面试150】——20有效的括号

博客昵称&#xff1a;沈小农学编程 作者简介&#xff1a;一名在读硕士&#xff0c;定期更新相关算法面试题&#xff0c;欢迎关注小弟&#xff01; PS&#xff1a;哈喽&#xff01;各位CSDN的uu们&#xff0c;我是你的小弟沈小农&#xff0c;希望我的文章能帮助到你。欢迎大家在…...

JWT介绍和结合springboot项目实践(登录、注销授权认证管理)

目录 一、JWT介绍&#xff08;一&#xff09;基本介绍&#xff08;二&#xff09;jwt有哪些库1、jjwt&#xff08;Java JWT&#xff09;2、nimbus - jwt - jwt - api 和 nimbus - jwt - jwt - impl3、spring - security - jwt&#xff08;已弃用&#xff0c;但在旧项目中有参考…...

Linux 下安装 Golang环境

Linux 下安装 Golang 获取Golang下载地址 安装 进入终端&#xff0c;登入root来到应用安装目录使用 wget 下载解压文件配置环境变量查看golang版本&#xff0c;测试是否配置成功GO设置代理环境变量 本篇教程 以 centos7 为环境基础 不使用软件包管理器安装&#xff0c;原因&am…...

「Mac畅玩鸿蒙与硬件36」UI互动应用篇13 - 数字滚动抽奖器

本篇将带你实现一个简单的数字滚动抽奖器。用户点击按钮后&#xff0c;屏幕上的数字会以滚动动画的形式随机变动&#xff0c;最终显示一个抽奖数字。这个项目展示了如何结合定时器、状态管理和动画实现一个有趣的互动应用。 关键词 UI互动应用数字滚动动画效果状态管理用户交…...

安装使用Ubuntu18.04超级大全集最初版(anaconda,pycharm,代理,c/c++环境)

本文介绍ubuntu1804中我目前用到的环境的完整配置&#xff0c;包括ubuntu安装软件&#xff0c;更新环境变量等都有涉及。图片非常多&#xff0c;能给的连接和材料都给了。希望能帮助到新同学。 目录 目录 目录 环境及镜像文件 安装Ubuntu ​编辑 开机之后 ​编辑 更新…...

Redis设计与实现第16章 -- Sentinel 总结1(初始化、主从服务器获取信息、发送信息、接收信息)

Sentinel是Redis的高可用解决方案&#xff1a;由一个或多个Sentinel实例组成的Sentinel系统可以监视任意多个主服务器&#xff0c;以及这些主服务器属下的所有从服务器&#xff0c;被监视的主服务器进入下线状态时&#xff0c;自动将下线主服务器属下的某个从服务器升级为新的主…...

ChatGPT科研应用、论文写作、课题申报、数据分析与AI绘图

随着人工智能技术的飞速发展&#xff0c;ChatGPT等先进语言模型正深刻改变着科研工作的面貌。从科研灵感的激发、论文的高效撰写&#xff0c;到课题的成功申报&#xff0c;乃至复杂数据的深度分析与可视化呈现&#xff0c;AI技术均展现出前所未有的潜力。其实众多科研前沿工作者…...

OceanBase数据库系列之:基于docker快速安装OceanBase数据库,基于linux服务器快速部署OceanBase数据库

OceanBase数据库系列之&#xff1a;基于docker快速安装OceanBase数据库&#xff0c;基于linux服务器快速部署OceanBase数据库 一、docker快速安装OceanBase数据库下载OceanBase数据库镜像查看镜像启动OceanBase数据库查看OceanBase数据库是否启动成功 二、基于linux部署OceanBa…...

无星的微前端之旅(四)——qiankun线上服务代理到本地

这个方式其实是我在上家公司的时候体验过&#xff0c;觉得确实很有意思。 所以这里来逆推一下实现方式。 解决了什么痛点 1.开发一个模块&#xff0c;需要启动2-3个项目 在微前端的开发过程中&#xff0c;如果我们要在主应用中看效果&#xff0c;我们至少需要启动一个主应用&am…...

鸿蒙进阶篇-Stage模型、UIAbility

“在科技的浪潮中&#xff0c;鸿蒙操作系统宛如一颗璀璨的新星&#xff0c;引领着创新的方向。作为鸿蒙开天组&#xff0c;今天我们将一同踏上鸿蒙基础的探索之旅&#xff0c;为您揭开这一神奇系统的神秘面纱。” 各位小伙伴们我们又见面了,我就是鸿蒙开天组,下面让我们进入今…...

快速上手:如何开发一个实用的 Edge 插件

在日常浏览网页时&#xff0c;背景图片能够显著提升网页的视觉体验。如果你也想为自己的浏览器页面添加个性化背景图片&#xff0c;并希望背景图片设置能够持久保存&#xff0c;本文将介绍如何通过开发一个自定义Edge插件来实现这一功能。我们将涵盖保存背景设置到插件选项页&a…...

java缓存技术点介绍

1. 缓存&#xff08;Cache&#xff09;&#xff1a; • 缓存是指用于存储数据的临时存储区域&#xff0c;以便快速访问。在Java中&#xff0c;缓存通常用于存储频繁访问的对象、结果集或其他数据。 2. 缓存命中率&#xff08;Cache Hit Ratio&#xff09;&#xff1a; • 缓存命…...

【单片机毕业设计12-基于stm32c8t6的智能称重系统设计】

【单片机毕业设计12-基于stm32c8t6的智能称重系统设计】 前言一、功能介绍二、硬件部分三、软件部分总结 前言 &#x1f525;这里是小殷学长&#xff0c;单片机毕业设计篇12-基于stm32c8t6的智能称重系统设计 &#x1f9ff;创作不易&#xff0c;拒绝白嫖可私 一、功能介绍 ----…...