css操作 文字居中显示: text-align:center;
布局纵向排列变成左右排列(盒子居左居右): display:flex;
DOM操作 神奇滤镜–DOM,display 勾选顶部复选框时,显示对应的滤镜面板;取消勾选时隐藏。多个面板叠加时,后选的面板显示在最上层querySelector('[data-filter-name="X"]')
:精确匹配特定属性值的元素 显示控制原理:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 filterTrigger.forEach ((trigger ) => { console .log (trigger); trigger.addEventListener ("click" , () => { const dataFilterName = trigger.getAttribute ("data-filter-name" ); filters.forEach ((item ) => { if (item.getAttribute ("data-filter-name" ) == dataFilterName) { item.hidden =!item.hidden updateZIndex (item) } }); }); });
图片 景深操作 元素的filter样式属性用于指定一个或多个滤镜效果,从而改变元素的外观。 blur():模糊元素。参数值表示模糊程度,单位为像素。 brightness():调整元素的亮度。参数值表示亮度的百分比。 contrast():调整元素的对比度。参数值表示对比度的百分比。 grayscale():将元素转换为灰度图像。参数值表示灰度的百分比。 hue-rotate():调整元素的色相。参数值表示旋转角度,单位为度数。 invert():反转元素的颜色。参数值表示反转的百分比。 opacity():调整元素的不透明度。参数值表示不透明度的百分比。 saturate():调整元素的饱和度。参数值表示饱和度的百分比。 sepia():将元素转换为褐色图像。参数值表示褐色的百分比。
1 2 document.querySelector (".img1 ").style .filter ="blur(0px )"; document.querySelector (".img2 ").style .filter ="blur(0px )";
动画 动一下的动画变得无限循环 animation-iteration-count: infinite; 解决:
1 2 3 animation : a3 0.8s steps (8 );变为 animation : a3 0.8s steps (8 ) infinite;
鼠标经过打开扇子 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 #box :hover div :first-child { transform : rotate (-60deg ); } #box :hover div :nth-child (2 ){ transform : rotate (-50deg ); } #box :hover div :nth-child (3 ){ transform : rotate (-40deg ); } #box :hover div :nth-child (4 ){ transform : rotate (-30deg ); } #box :hover div :nth-child (5 ){ transform : rotate (-20deg ); } #box :hover div :nth-child (6 ){ transform : rotate (-10deg ); } #box :hover div :nth-child (7 ){ transform : rotate (10deg ); } #box :hover div :nth-child (8 ){ transform : rotate (20deg ); } #box :hover div :nth-child (9 ){ transform : rotate (30deg ); } #box :hover div :nth-child (10 ){ transform : rotate (40deg ); } #box :hover div :nth-child (11 ){ transform : rotate (50deg ); } #box :hover div :nth-child (12 ){ transform : rotate (60deg ); }
flex: 单个子项位置align-self 先后顺序order:3 主轴方向flex-direction 换不换行flex-wrap
元素周期表–var,cal计算
已知:元素周期表(class=table)中一共有 18 列(class=list)元素,请使用 flex布局,使元素周期表中的 18 列元素横向排列。请使用 var、calc 函数设置第2、13~17列元素(class=interval1)的 margin-top 为 1 个元素的高度,设置第3~12列元素(class=interval3)的 margin-top 为 3 个元素的高度。 一个元素的高度已定义变量如下:
1 2 3 :root { --interval : 66px ; }
css 变量 以及 calc 计算 使用案例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 :root { --main-color : #3498db ; --padding-size : 16px ; } .button { color : var (--main-color); padding : calc (var (--padding-size) / 2 ); }
作答:
1 2 3 4 5 6 7 8 9 10 11 12 .container .table { display : flex; } .container .table .interval1 { margin-top : var (--interval); } .container .table .interval3 { margin-top : calc (var (--interval) * 3 ); }
名片修改–居中练习 名片整体页面居中;名片左部分的各子项居中
1 2 3 4 5 body ,.user-card { display : flex; justify-content : center; align-items : center; }
蔬菜–控制每个子项位置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 #box1 ,#box2 ,#box3 { display : flex; } #box1 { justify-content : center; align-items :center; } #box2 { justify-content : space-between; } #box2 .item :nth-child (2 ) { align-self : end; } #box3 { justify-content : space-between; } #box3 .item :nth-child (2 ) { align-self : center; } #box3 .item :nth-child (3 ) { align-self : end; }
grid 电影院排座位 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 <!DOCTYPE html > <html lang ="zh-CN" > <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 ="./css/style.css" /> </head > <body > <div class ="container" > <div class ="screen" > 阿凡达2</div > <div class ="seat-area" > <div class ="seat" > </div > <div class ="seat" > </div > <div class ="seat" > </div > <div class ="seat" > </div > <div class ="seat" > </div > <div class ="seat" > </div > <div class ="seat" > </div > <div class ="seat" > </div > <div class ="seat" > </div > <div class ="seat" > </div > <div class ="seat" > </div > <div class ="seat" > </div > <div class ="seat" > </div > <div class ="seat" > </div > <div class ="seat" > </div > <div class ="seat" > </div > <div class ="seat" > </div > <div class ="seat" > </div > <div class ="seat" > </div > <div class ="seat" > </div > <div class ="seat" > </div > <div class ="seat" > </div > <div class ="seat" > </div > <div class ="seat" > </div > <div class ="seat" > </div > <div class ="seat" > </div > <div class ="seat" > </div > <div class ="seat" > </div > <div class ="seat" > </div > <div class ="seat" > </div > <div class ="seat" > </div > <div class ="seat" > </div > <div class ="seat" > </div > <div class ="seat" > </div > <div class ="seat" > </div > <div class ="seat" > </div > <div class ="seat" > </div > <div class ="seat" > </div > <div class ="seat" > </div > <div class ="seat" > </div > <div class ="seat" > </div > <div class ="seat" > </div > <div class ="seat" > </div > <div class ="seat" > </div > <div class ="seat" > </div > <div class ="seat" > </div > <div class ="seat" > </div > <div class ="seat" > </div > </div > </div > </body > </html >
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 * { box-sizing : border-box; } body { background-color : #242333 ; color : #fff ; display : flex; flex-direction : column; align-items : center; justify-content : center; height : 100vh ; margin : 0 ; } .container { perspective : 1000px ; width : 470px ; } .screen { background-color : #fff ; height : 70px ; width : 100% ; transform : rotateX (-45deg ); box-shadow : 0 3px 10px rgba (255 , 255 , 255 , 0.7 ); color : #242333 ; text-align : center; line-height : 70px ; font-size : 30px ; } .seat { background-color : #444451 ; height : 40px ; width : 45px ; border-top-left-radius : 10px ; border-top-right-radius : 10px ; } .seat-area { margin-top : 50px ; display : grid; gap : 10px ; grid-template-columns : repeat (2 , 45px 65px 45px 45px ); } .seat-area { margin-top :50px ; display : flex; flex-wrap : wrap; gap :10px ; } .seat-area .seat :nth-of-type (8 n+2 ){ margin-right :20px } .seat-area .seat :nth-of-type (8 n+6 ){ margin-right :20px }
页面 页面表单 页面整体布局,要求如图
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 .content-container {margin-top : 70px ;} .content { height : 600px ; width : 450px ; background-color : rgba (0 , 0 , 0 , .45 ); margin : 0 auto; border-radius : 10px ; text-align : center; } .content img { width : 200px ; height : 200px ; border-radius : 50% ; margin-top : -20% ; } .content h2 { font-size : 45px ; font-weight : 800 ; margin-bottom : 40px ; } .content button { width : 80px ; height : 30px ; border-color : #041c32 ; background-color : #2d4263 ; color : white; margin-top : 15px ; } .content a { text-decoration : none; color : white; } .text { margin-top : 15px ; } .content input { text-align : center; width : 300px ; height : 40px ; font-size : 20px ; border-radius : 5px ; margin : 10px ; }
js操作 数组 提取对象数组的Key返回一个数组并去重
请在 TODO 2 处补全代码,实现函数 extractUniquePoints 的封装,该函数接收一个二维数组 data 作为参数(即为目标 1 中获取到的 rawData 变量的值),并把二维数组 data 中的 points 属性值提取出来并去重,最终存储在一个一维数组中返回。最终返回的数据结构如下:["DOM 操作","ElementPlus","Vue.js"]
两种解答方法:
1 2 3 4 5 6 7 8 9 10 11 12 function extractUniquePoints (data ) { const arr2=[] data.forEach (item => { for (const key of item.points ){ arr2.push (key) } }) return [...new Set (arr2)] }
第二种,用flat(),但是这个我不是很懂,这样的话怎么就只取key了呢,value不会也进去吗
1 2 3 4 5 function extractUniquePoints (data ) {return [...new Set (data.flat (1 ).map (item => item.points ).flat (1 ))] }
知识点
数组升序arr.sort((a, b) => a - b);
数组降序arr.sort((a, b) => b - a);
为什么要用比较函数? 若数组是 [10, 2],默认排序会得到 [10, 2](因为字符串 ‘10’ 的 Unicode 码点比 ‘2’ 小),但比较函数 a - b 会正确排序为 [2, 10]arr.slice(start, end)
:截取从 start 到 end - 1 的元素(不包含 end)result.push(arr.slice(i, i + sliceNum));
push() 方法:将子数组添加到 result 的末尾
在编程中,cb 是 回调函数(Callback Function) 的常见缩写。它是一个函数,作为参数传递给另一个函数,并在某个特定条件满足时被调用
将对象转化成数组Object.entries(params)
1 2 const params = { name : 'Alice' , age : 25 };Object .entries (params)
小狼人–重写filter回调函数 1 2 3 4 5 6 7 8 Array .prototype .myarray = function (cb ) { const newArr = [] for (const value of this ) { if (cb (value)) newArr.push (value) } return newArr };
1 2 3 4 5 6 7 8 9 10 11 12 13 Array .prototype .myarray = function (cb ) { const result = []; for (let i = 0 ; i < this .length ; i++) { const currentElement = this [i]; if (cb (currentElement, i, this )) { result.push (currentElement); } } return result; };
this 的指向:在 Array.prototype.myarray 中,this 指向调用该方法的数组(如 cardList)。 回调函数参数:filter 的回调函数接受三个参数:(element, index, array),需保持一致性
更好的解法:
1 2 3 4 5 6 7 8 9 10 11 12 Array .prototype .myarray = function (cb ) { let result = []; this .forEach (item => { if (cb (item)) { result.push (item); } }); return result };
解密数组–回溯函数 从1到max中选择count个不同的数,并按升序排列
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 function getPossiblePasswords (max, count ) { const result = []; if (count === 0 || max < count) return result; function backtrack (start, path ) { if (path.length === count) { result.push ([...path]); return ; } for (let i = start; i <= max; i++) { path.push (i); backtrack (i + 1 , path); path.pop (); } } backtrack (1 , []); return result; }
分割数组 一个数组,将它分割成指定长度的若干份;升序排序
具体要求: 将待分割的(一维)数组升序排序。 将排序后的数组从下标为 0 的元素开始,按照从 id=sliceNum 的输入框中获取到的数值去分割,并将分割好的数据存入一个新数组中。如:输入框中值为 n,将原数组按每 n 个一组分割,不足 n 个的数据为一组。 将得到的新数组返回(即 return 一个二维数组)
1 2 3 4 const splitArray = (oldArr, num ) => { }; modul
解答 1 2 3 4 5 6 7 8 9 10 11 const splitArray = (oldArr, num ) => { oldArr.sort ((a, b ) => a - b); const result = []; for (let i = 0 ; i < oldArr.length ; i += num) { result.push (oldArr.slice (i, i + num)); } return result; };
垃圾分类–对象数组分类 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 const waste = ref ([{ type : "厨余垃圾" , txt : "剩菜剩饭" , dis : [10 , 30 , 100 , 33 ] },{ type : "厨余垃圾" , txt : "骨头" , dis : [185 , 28 , 50 , 33 ] }, { type : "厨余垃圾" , txt : "菜根菜叶" , dis : [550 , 169 , 100 , 33 ] }, { type : "可回收垃圾" , txt : "废纸" , dis : [20 , 100 , 50 , 33 ] }, { type : "可回收垃圾" , txt : "塑料" , dis : [8 , 170 , 50 , 33 ] }, { type : "可回收垃圾" , txt : "玻璃" , dis : [155 , 140 , 50 , 33 ] }, { type : "可回收垃圾" , txt : "金属" , dis : [400 , 150 , 50 , 33 ] }, { type : "可回收垃圾" , txt : "布料" , dis : [105 , 60 , 50 , 33 ] }, { type : "其他垃圾" , txt : "砖瓦陶瓷" , dis : [520 , 120 , 100 , 33 ] }, { type : "其他垃圾" , txt : "渣土" , dis : [600 , 30 , 50 , 33 ] }, { type : "其他垃圾" , txt : "卫生间废纸" , dis : [185 , 100 , 125 , 33 ] }, { type : "有害垃圾" , txt : "废电池" , dis : [350 , 100 , 75 , 33 ] }, { type : "有害垃圾" , txt : "废日光灯管" , dis : [500 , 60 , 125 , 33 ] }, { type : "有害垃圾" , txt : "废水银温度计" , dis : [305 , 35 , 150 , 33 ] }, { type : "有害垃圾" , txt : "过期药品" , dis : [255 , 167 , 100 , 33 ] }, ]); let food_waste = ref ([]); let recyclable_waste = ref ([]); let other_waste = ref ([]); let harmful_waste = ref ([]); window .food_waste = food_waste;
waste.value 是一个数组,其中每个元素是一个对象,包含以下属性:type,txt,dis。
1 2 3 waste.value .forEach (res => { });
forEach 是 JavaScript 中用于遍历数组的方法。 res 是当前遍历到的数组元素(即一个垃圾对象)。 forEach 不会返回新数组,它只是对数组中的每个元素执行回调函数。
let food_waste = ref([]);
ref([]) 是 Vue 3 中定义响应式数据的方式,表示一个初始值为空数组的响应式变量。 food_waste.value 是实际存储数据的地方。由于 ref 返回的是一个对象,必须通过 .value 访问或修改数据。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 const garbagesorting = ( ) => { console .log (waste.value ); waste.value .forEach (res => { if (res.type =="厨余垃圾" ) { food_waste.value .push (res.txt ) } if (res.type =="可回收垃圾" ) { recyclable_waste.value .push (res.txt ) } if (res.type =="其他垃圾" ) { other_waste.value .push (res.txt ) } if (res.type =="有害垃圾" ) { harmful_waste.value .push (res.txt ) } }) };
帛书碎片–数组去重 1 2 3 4 5 6 7 8 9 function collectPuzzle (...puzzles ) { const newPuz = []; for (const k of puzzles) { k.forEach (item => { if (!newPuz.includes (item)) newPuz.push (item); }); } return newPuz; }
我的作答
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 function collectPuzzle (...puzzles ) { console .log (...puzzles)const res=[]for (const k of puzzles){ k.forEach (element => { if (!res.includes (element)){ res.push (element) } }); } return res}
偏门作答(学习新知识) flat给数组降维,默认是flat(1)就是降维一次,本来传的是个二维数组变成一维数组了,然后Set可以自动去重再生成一个去重后的新数组
1 return [...new Set (puzzles.flat ())]
字符串拼接 分享链接–对象转数组+url拼接 思路是把对象转化成指定要求的数组拼接起来,两种方法:
第一种,使用Object.keys(对象)
返回对象的key组成的数组arr1 再用arr1.map()遍历key,返回要的格式
第二种,使用Object.entries(对象)
返回对象的key和value组成的数组arr2 再用arr2.map()遍历key和value,返回要的格式 拼接字符串也是两种方法:
模板字符串`${key}=${params[key]}`
直接拼key+"="+params[key]
第一种方法代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 function appendParamsToURL (url, params ) { const nparams = Object .keys (params).map ((p )=> `${p} =${params[p]} ` ).join ("&" ) if (url.includes ("?" )){ return `${url} &${nparams} ` } else { return `${url} ?${nparams} ` } }
第二种Object.entries()
方法代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 function appendParamsToURL (url, params ) { var nparams = Object .entries (params) console .log (nparams) var arr =nparams.map (([key,value] )=> key+"=" +value).join ("&" ) console .log (arr)if (url.includes ("?" )){ string = url+"&" +arr return string } else { string = url+"?" +arr return string } }
将对象转为查询字符串 params = Object.keys(params).map((p) => `${p}=${params[p]}`).join("&");
功能:将 params 对象转换为 URL 查询字符串(如 name=Bob&age=25)。 关键步骤分解: Object.keys(params): 获取 params 对象的所有键(属性名),形成一个数组。 例如:{ name: ‘Bob’, age: 25 } → [‘name’, ‘age’]。 map((p) => …): 遍历键数组中的每个键 p(如 ‘name’)。 将键和对应的值拼接为 key=value 的字符串。 例如:p = ‘name’ → params[p] 是 ‘Bob’ → 结果为 “name=Bob”。 .join(‘&’): 将所有 key=value 字符串用 & 连接,形成最终的查询字符串。 例如:[“name=Bob”, “age=25”] → “name=Bob&age=25”
水印生成–innerHtml拼接元素 两种解答方式
1 2 3 4 5 6 7 8 9 10 11 12 13 for (let i = 0 ; i < count; i++) { let Aspan = document .createElement ('span' ); Aspan .innerHTML = text; Aspan .style .color = color; Aspan .style .opacity = opacity; Aspan .style .transform = `rotate(${deg} deg)` ; container.appendChild (Aspan ); } for (var i=0 ;i<count;i++){ container.innerHTML += `<span style="color:${color} ;transform:rotate(${deg} deg);opacity:${opacity} ">${text} </span>` }
方法一: 创建元素:通过 document.createElement(‘span’) 创建一个新的 <span>
元素。 设置属性:使用 .innerHTML 来设置 <span>
的文本内容,.style 属性来逐个设置样式(颜色、透明度、旋转角度)。 追加到DOM:使用 .appendChild() 方法将新创建的 <span>
元素添加到指定的容器(container)中 方法二: 字符串拼接:在循环内部,构建一个包含所需<span>
元素及其样式的字符串。 追加HTML:使用 += 操作符将这个字符串追加到 container.innerHTML 中,这意味着每次迭代都会修改容器的HTML内容
欢迎语拼接 注意第二种获取内容.value
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 function generate ( ) { subject = document .getElementById ("subject" ).value ; event1 = document .getElementById ("event1" ).value ; event2 = document .getElementById ("event2" ).value ; if (subject.length ==0 || event1.length ==0 || event2.length ==0 ){ return ; } result = "欢迎用户" +subject+"在" +event2+"学习" +event1+"课程!" ; document .getElementById ("result" ).value = result; } function generate ( ) { subject = document .getElementById ("subject" ); event1 = document .getElementById ("event1" ); event2 = document .getElementById ("event2" ); if (subject.length ==0 || event1.length ==0 || event2.length ==0 ){ return ; } result = `欢迎用户${subject.value} 在${event2.value} 学习${event1.value} 课程!` ; document .getElementById ("result" ).value = result; }
正则表达式 添加千分位 原代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 <!DOCTYPE html > <html > <head > <meta charset ="utf-8" /> <meta name ="viewport" content ="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" /> <meta http-equiv ="Cache-Control" content ="no-store" /> <title > 你能看出有多少位吗?</title > <link rel ="stylesheet" href ="https://labfile.oss.aliyuncs.com/courses/9203/style05.css" > </head > <body > <div class ="wrap" > <form action ="" class ="edit-cash" > <p > 消费总额</p > <div class ="shuru" > <span > ¥ </span > <div id ="input-box" > </div > </div > <p > 可询问工作人员应缴费用总额</p > </form > <input type ="submit" value ="支付" class ="submit" /> </div > <div class ="layer" > </div > <div class ="form" > <form action ="" method ="post" > <input type ="text" placeholder ="姓名" /> <input type ="text" placeholder ="联系电话" /> <input type ="submit" value ="提交" class ="infor-sub" /> </form > </div > <div class ="layer-content" > <div class ="form-edit clearfix" > <div class ="num num1" > 1</div > <div class ="num num2" > 2</div > <div class ="num num3" > 3</div > <div class ="num num4" > 4</div > <div class ="num num5" > 5</div > <div class ="num num6" > 6</div > <div class ="num num7" > 7</div > <div class ="num num8" > 8</div > <div class ="num num9" > 9</div > <div class ="num num0" > 0</div > <div id ="remove" > 删除</div > </div > </div > <script src ="https://labfile.oss.aliyuncs.com/courses/9203/jquery.min.js" > </script > <script > $(function ( ){ $('.infor-sub' ).click (function (e ){ $('.layer' ).hide (); $('.form' ).hide (); e.preventDefault (); }) $('.shuru' ).click (function (e ){ $('.layer-content' ).animate ({ bottom : 0 }, 200 ) e.stopPropagation (); }) $('.wrap' ).click (function ( ){ $('.layer-content' ).animate ({ bottom : '-200px' }, 200 ) }) $('.form-edit .num' ).click (function ( ){ var oDiv = document .getElementById ("input-box" ); oDiv.innerHTML += this .innerHTML ; }) $('#remove' ).click (function ( ){ var oDiv = document .getElementById ("input-box" ); var oDivHtml = oDiv.innerHTML ; oDiv.innerHTML = oDivHtml.substring (0 ,oDivHtml.length -1 ); }) }) </script > </body > </html >
作答
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 <!DOCTYPE html > <html > <head > <meta charset ="utf-8" /> <meta name ="viewport" content ="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" /> <meta http-equiv ="Cache-Control" content ="no-store" /> <title > 你能看出有多少位吗?</title > <link rel ="stylesheet" href ="https://labfile.oss.aliyuncs.com/courses/9203/style05.css" /> </head > <body > <div class ="wrap" > <form action ="" class ="edit-cash" > <p > 消费总额</p > <div class ="shuru" > <span > ¥ </span > <div id ="input-box" > </div > </div > <p > 可询问工作人员应缴费用总额</p > </form > <input type ="submit" value ="支付" class ="submit" /> </div > <div class ="layer" > </div > <div class ="form" > <form action ="" method ="post" > <input type ="text" placeholder ="姓名" /> <input type ="text" placeholder ="联系电话" /> <input type ="submit" value ="提交" class ="infor-sub" /> </form > </div > <div class ="layer-content" > <div class ="form-edit clearfix" > <div class ="num num1" > 1</div > <div class ="num num2" > 2</div > <div class ="num num3" > 3</div > <div class ="num num4" > 4</div > <div class ="num num5" > 5</div > <div class ="num num6" > 6</div > <div class ="num num7" > 7</div > <div class ="num num8" > 8</div > <div class ="num num9" > 9</div > <div class ="num num0" > 0</div > <div id ="remove" > 删除</div > </div > </div > <script src ="https://labfile.oss.aliyuncs.com/courses/9203/jquery.min.js" > </script > <script > $(function ( ) { $(".infor-sub" ).click (function (e ) { $(".layer" ).hide (); $(".form" ).hide (); e.preventDefault (); }); $(".shuru" ).click (function (e ) { $(".layer-content" ).animate ( { bottom : 0 , }, 200 ); e.stopPropagation (); }); $(".wrap" ).click (function ( ) { $(".layer-content" ).animate ( { bottom : "-200px" , }, 200 ); }); let num = "" ; $(".form-edit .num" ).click (function ( ) { num += this .innerHTML ; updateDisplay (); }); $("#remove" ).click (function ( ) { if (num.length > 0 ) { num = num.slice (0 , -1 ); updateDisplay (); } }); function updateDisplay ( ) { const formatted = formatNumber (num); $("#input-box" ).text (formatted); } function formatNumber (str ) { return str .replace (/\D/g , "" ) .replace (/(\d)(?=(\d{3})+(?!\d))/g , "$1," ); } }); </script > </body > </html >
讲解 num = num.slice(0, -1);
始终删除最后一个数字字符if (num.length > 0) { ... }
防止空字符串操作return str.replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1,');
反向遍历的正则表达式 (\d):匹配单个数字并捕获 (?=(\d{3})+(?!\d)):后面跟着3的倍数位数的位置 $1,:在匹配位置插入逗号
验证密码强度 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 <!DOCTYPE html > <html lang ="zh" > <head > <meta charset ="UTF-8" > <meta http-equiv ="X-UA-Compatible" content ="IE=edge,chrome=1" > <meta name ="viewport" content ="width=device-width, initial-scale=1.0" > <title > 验证密码强度</title > <link href ="https://labfile.oss.aliyuncs.com/courses/9203/bootstrap.min.css" rel ="stylesheet" > <style > .bg { overflow : hidden; background-color : beige; } </style > </head > <body > <section class ="bg" > <div class ="container col-sm-12" > <div class ="col-sm-4 col-sm-offset-4" autocomplete ="off" > <fieldset > <legend style ="color: #0e0e0e" > 注 册</legend > <div class ="form-group" > <label for ="passwordField" > Password</label > <input type ="password" name ="passwordField" id ="passwordField" class ="form-control" required ='required' /> </div > </fieldset > <div > <button type ="button" class ="btn btn-primary btn-validate" > 验证</button > <span > 强度等级:</span > <span class ="result" > 未验证</span > </div > </div > </div > <div class ="container col-sm-12" > <br /> <div class ="col-sm-12 col-sm-offset-4" > <p > <strong > 你填写的密码的强度等级按如下划分:</strong > </p > <dl > <dt > 低:</dt > <ol > <li > 密码必须大于 8 个字符</li > </ol > <dt > 中(在满足低强度要求的前提下,需要满足以下需求):</dt > <dd > <ol > <li > 至少需要一个小写字母</li > <li > 至少需要一个数字</li > </ol > </dd > <dt > 高(在满足中强度要求的前提下,需要满足以下需求):</dt > <dd > <ol > <li > 至少需要一个大写字母</li > <li > 至少需要一个(除数字和字母外的)特殊字符</li > </ol > </dd > </dl > </div > </div > </section > <script src ="https://labfile.oss.aliyuncs.com/courses/9203/jquery.min.js" > </script > <script > </script > </body > </html >
作答:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 document .querySelector ('button' ).addEventListener ('click' ,function ( ){ let str = document .querySelector ('input' ).value console .log (str) if (str.length >8 ){ document .querySelector ('.result' ).innerHTML ='低' const regaz = /[a-z]/g const regnum = /[0-9]/g if (str.match (regaz)&&str.match (regnum)){ document .querySelector ('.result' ).innerHTML ='中' const regdaz = /[A-Z]/g const regzf = /[^0-9a-zA-Z]/g if (str.match (regdaz)&&str.match (regzf)){ console .log ('111' ) document .querySelector ('.result' ).innerHTML ='高' } } }else { document .querySelector ('.result' ).innerHTML ='无效' } })
说明 是否使用 /g 标志其实并不影响结果,因为你在使用 .match() 方法时,只关心是否存在匹配项(即结果是否为 null),而不是具体的匹配内容或数量。因此,在这种情况下,可以省略 /g 标志以简化
多表单校验 要求:
完善 index.html TODO 部分,实现多表单校验功能。 两个表单校验规则(rules)如下: 姓名:必填。规则:只能输入汉字。提示:请输入姓名,只能输入汉字。 性别:必填。提示:请选择性别。 年龄:必填。提示:请输入年龄。 是否参加过编程比赛:必填。提示:请选择是否参加过编程比赛。 是否有过创业经历:必填。提示:请选择是否有过创业经历。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 const rules = reactive ({ name : { required : true , validator : (rule, value, callback ) => { if (value === '' ) { callback ('请输入姓名' ) } else if (/[^\u4e00-\u9fa5]/g .test (value)) { callback ('只能输入汉字' ) } else { callback () } } }, sex : { required : true , message : '请选择性别' }, age : { required : true , message : '请输入年龄' }, isCompetition : { required : true , message : '请选择是否参加过编程比赛' }, isEntrepreneurship : { required : true , message : '请选择是否有过创业经历' } })
封装函数 找回链接之旅–可重置的单次执行函数(难懂) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 function resetableOnce (fn ) { let flag = true ; let result; function runOnce (...arr ) { console .log (...arr); if (flag) { result = fn (...arr); flag = false ; return result; } else { return result; } } function reset ( ) { result = undefined ; flag = true ; } return { runOnce, reset }; }
360动画展示–管道模式–异步函数封装 等待每一个动画执行完毕之后,再执行下一个动画,并把前一个动画的返回值initialValue返回,以保持动画的衔接。
1 2 3 4 5 6 7 const pipeline = async (initialValue, sequence ) => { for (let fn of sequence) { initialValue = await Promise .resolve (fn (initialValue)); } return initialValue; };
initialValue 就是原材料。 sequence 是一个函数数组,每个函数代表一个加工步骤。 pipeline 函数的作用就是按顺序执行这些步骤,每一步的输出作为下一步的输入。
知识点 Promise是处理异步操作的对象,有三种状态:pending(进行中)、fulfilled(已完成)、rejecte(已失败) 异步操作(如网络请求、定时器)通常通过回调函数来处理结果。但回调函数会导致回调地狱(Callback Hell),代码结构混乱,难以维护
async: 修饰函数,表示该函数返回一个 Promise。 函数内部可以使用 await 关键字。 await: 只能在 async 函数内部使用。 暂停函数执行,等待 Promise 完成(fulfilled),并获取其结果。 如果 Promise 被 reject,会抛出错误,可以用 try/catch 捕获
布局切换–添加移除类名 实现被点击的模式元素(class=layout-option)处于激活状态,即添加一个类名(active),其他(class=layout-option)移除激活状态,即移除类名(active)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 const layoutOptions = document .querySelectorAll ('.layout-option' ); switching.addEventListener ('click' , function ( ) { mode.style .display = 'flex' ; }); layoutOptions.forEach (function (option ) { option.addEventListener ('click' , function ( ) { layoutOptions.forEach (item => { item.classList .remove ('active' ) }) this .classList .add ("active" )
选项卡功能 它通过点击不同的div元素来切换显示对应的内容区域 原Html代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 <!DOCTYPE html > <html > <head > <meta charset ="utf-8" /> <title > 选项卡切换</title > <link rel ="stylesheet" type ="text/css" href ="./css/index.css" /> </head > <body > <div id ="main" > <div class ="tabs" > <div class ="active" > 选项一</div > <div > 选项二</div > <div > 选项三</div > <div > 选项四</div > </div > <div id ="content" > <div id ="one" class ="active" > <p > 爱情要完结的时候自会完结,到时候,你不想画上句号也不行。爱情,原来是含笑饮毒酒。 </p > <img src ="./imgs/1.jpeg" /> </div > <div id ="two" > <p > 在这个光怪陆离的人间,没有谁可以将日子过的行云流水。但我始终相信,走过平湖山雨,岁月山河,那些历尽劫数,尝遍百味的人,会更加生动而干净。 </p > <img src ="./imgs/2.jpeg" /> </div > <div id ="three" > <p > 对于三十岁以后的人来说,十年八年不过是指缝间的事,而对于年轻人而言,三年五年就可以是一生一世。 </p > <img src ="./imgs/3.jpeg" /> </div > <div id ="four" > <p > 我要你知道,在这个世界上总有一个人是等着你的,不管在什么时候,不管在什么地方,反正你知道,总有这么个人。 </p > <img src ="./imgs/4.jpeg" /> </div > </div > </div > </body > <script src ="./js/index.js" type ="text/javascript" charset ="utf-8" > </script > </html >
要补充的代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 function init ( ) { var divs = document .querySelectorAll ('.tabs>div' ); var imgs = document .querySelectorAll ('#content>div' ); for (let i = 0 ; i < divs.length ; i++) { divs[i].onclick = function ( ) { for (let a = 0 ; a < divs.length ; a++) { divs[a].classList .remove ('active' ); imgs[a].classList .remove ('active' ); } divs[i].classList .add ('active' ); imgs[i].classList .add ('active' ); } } } init ();
注意
在这段代码中,classList.remove(‘active’)用来确保每次点击时先清除之前设置的激活状态,然后再用classList.add(‘active’)来设置新的激活状态。 当你调用classList.remove()并传递一个参数如’active’时,你实际上是在告诉JavaScript:“请从这个元素的class属性中移除名为active的类。” 工作原理:此方法接受一个或多个类名(不带.前缀)作为参数 ,并尝试从元素的class列表中删除这些类。如果该类存在于元素上,则它将被移除;如果不存在,则什么也不会发生。classList方法期望的是纯粹的类名字符串,而不包含任何CSS选择器符号(如.代表类选择器)
选择器 实时与静态更新: document.querySelectorAll(‘.tabs>div’) 和 document.querySelectorAll(‘#content>div’): 这两个调用使用的是CSS选择器语法来选择元素。querySelectorAll方法返回一个静态的NodeList,包含所有匹配给定选择器的元素。 .tabs>div表示选择所有直接位于具有.tabs类的元素下的div元素;#content>div同理,但它是基于ID选择器#content。
使用getElementsByClassName(‘.tabs’)是不正确的 ,因为getElementsByClassName接受一个参数,即一个或多个类名(不带.),并且它会返回一个实时更新的HTMLCollection。因此,正确的方式应该是document.getElementsByClassName(‘tabs’),但这只会返回拥有tabs类的所有元素,而不能用于直接选择.tabs下的子div元素 。 实时与静态集合: HTMLCollection(动态)会随DOM变化自动更新 NodeList(静态)是选择时的快照 getElementsByClassName和getElementsByTagName返回的是实时的HTMLCollection,这意味着如果文档中的元素发生了变化,这个集合也会随之更新。相反,querySelectorAll返回的是静态的NodeList,即使文档发生变化,这个列表也不会改变。 性能考量:对于简单的选择操作,getElementsByClassName和getElementsByTagName可能会比querySelectorAll更快,尤其是在处理大量元素时。然而,querySelectorAll提供了更大的灵活性,特别是在处理复杂的选择器时。 综上所述,如果你想根据类名和父子关系精确选择元素,querySelectorAll是最适合的选择之一。
优化方向 1 2 3 4 5 6 document .querySelector ('.tabs' ).addEventListener ('click' , function (e ) { if (e.target .tagName === 'DIV' ) { } });
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 function init ( ) { const tabsContainer = document .querySelector ('.tabs' ); const content = document .getElementById ('content' ); tabsContainer.addEventListener ('click' , function (e ) { const clickedTab = e.target .closest ('.tabs > div' ); if (!clickedTab) return ; const index = Array .prototype .indexOf .call ( tabsContainer.children , clickedTab ); const prevActiveTab = tabsContainer.querySelector ('.active' ); const prevActiveContent = content.querySelector ('.active' ); if (prevActiveTab) prevActiveTab.classList .remove ('active' ); if (prevActiveContent) prevActiveContent.classList .remove ('active' ); clickedTab.classList .add ('active' ); content.children [index].classList .add ('active' ); }); }
新年贺卡(逻辑+随机数)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 <!DOCTYPE html > <html > <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 > Document</title > <link rel ="stylesheet" href ="index.css" > </head > <body > <div class ="card-name" > 新年贺卡</div > <div class ="card" id ="card" > <p id ="greeting-display" > </p > </div > <button id ="btn" > 书写贺卡</button > <script src ="./index.js" > </script > </body > </html >
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 document .addEventListener ('DOMContentLoaded' , function ( ) { const greetingDisplay = document .getElementById ("greeting-display" ) const btn = document .getElementById ("btn" ) btn.addEventListener ("click" , () => { show (greetingDisplay) }) }) const greetings = [ "新年快乐!" , "接受我新春的祝愿,祝你平安幸福" , "祝你新年快乐,洋洋得意!" , "新的一年,新的开始;心的祝福,新的起点!" , "新年好!祝新年心情好,身体好,一切顺心!" , ] function writeGreeting ( ) { const randomIndex = Math .floor (Math .random () * greetings.length ); return greetings[randomIndex]; } function show (greetingDisplay ) { const greeting = writeGreeting (); greetingDisplay.textContent = greeting; } module .exports = { show, writeGreeting }
随机数生成器(指定范围和个数的不重复的随机数数组) 生成指定范围和个数的不重复的随机数数组
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 <!DOCTYPE html > <html > <head > <meta charset ="utf-8" > <title > </title > <script src ="./js/index.js" > </script > </head > <body > <script type ="text/javascript" > var testArr = getRandomNum (1 ,30 ,3 ); document .write ("<h1>1-30 以内的 3 个随机数:" +testArr+"</h1>" ); testArr = getRandomNum (1 ,100 ,10 ); document .write ("<h1>1-100 以内的 10 个随机数:" +testArr+"</h1>" ); </script > </body > </html >
作答部分:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 const getRandomNum = function (min, max, countNum ) { var arr = []; while (arr.length < countNum) { var num = Math .floor (Math .random () * (max - min + 1 ) + min); if (arr.indexOf (num) === -1 ) { arr.push (num); } } return arr; } module .exports = getRandomNum; `` ` #### 知识点 生成` `[min,max]` `区间的随机整数公式 ` `Math.floor(Math.random() * (max - min + 1)) + min` ` textContent:安全设置纯文本内容 innerHTML:可以插入HTML标签(本题不需要) #### 相关:洗牌算法 这种方法提供了一种有效且公平的方式来从一系列数字中随机抽取若干个不重复的数字。 ` `` jsconst getRandomNum = function (min, max, countNum ) { let pool = []; for (let i = min; i <= max; i++) { pool.push (i); } for (let i = pool.length - 1 ; i > 0 ; i--) { const j = Math .floor (Math .random () * (i + 1 )); [pool[i], pool[j]] = [pool[j], pool[i]]; } return pool.slice (0 , countNum); };
生成数值范围池: 使用一个循环从min到max遍历,并将每个值添加到pool数组中。 这一步的结果是一个包含了所有可能数值的数组,例如如果min是1,max是5,则pool会是[1, 2, 3, 4, 5]。 Fisher-Yates洗牌算法: 这是一种高效的算法,用于生成一个均匀随机排列的数组。对于每一个数组中的元素,选择一个随机位置与之交换,从而达到打乱数组的目的。 Math.floor(Math.random() * (i + 1))生成一个介于0和当前索引i之间的随机整数j。 [pool[i], pool[j]] = [pool[j], pool[i]]这行代码使用了ES6的解构赋值特性,交换数组中两个元素的位置。 截取前countNum个元素: 使用Array.prototype.slice()方法复制数组的一部分。这里是从数组的开始处(索引为0)开始,复制countNum个元素。 这样就得到了一个由原数组中随机选出的、不重复的countNum个元素组成的数组。
相关:随机颜色生成 1 2 3 function randomColor ( ) { return '#' + Math .floor (Math .random ()*0xffffff ).toString (16 ).padStart (6 ,0 ); }
卡片化标签页(排他算法) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 function init ( ) { var divs = document .querySelectorAll ('.tabs>div' ); var imgs = document .querySelectorAll ('#content>div' ); for (let i = 0 ;i<divs.length ;i++) { divs[i].onclick =function ( ){ for (let a = 0 ;a<divs.length ;a++) { divs[a].classList .remove ('active' ); imgs[a].classList .remove ('active' ); } divs[i].classList .add ('active' ); imgs[i].classList .add ('active' ); } } } init ();
加减乘除计算 (switch case语句) 提供代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 <!DOCTYPE html > <html > <head > <meta http-equiv ="Content-Type" content ="text/html; charset=utf-8" /> <title > 简易计算器</title > </head > <body > <h3 > 计算器</h3 > <input type ="number" id ="num1" size ="10" /> <select id ="type" > <option value ="0" > +</option > <option value ="1" > -</option > <option value ="2" > *</option > <option value ="3" > /</option > </select > <input type ="number" id ="num2" size ="10" /> <input type ="button" value ="计算" id ="btnsubmit" /> <p id ="val" > </p > </body > <script type ="text/javascript" src ="cal.js" > </script > <script > document .getElementById ("btnsubmit" ).onclick = function ( ) { var num1 = document .getElementById ("num1" ).value ; var num2 = document .getElementById ("num2" ).value ; var type = document .getElementById ("type" ).value ; if (type == 3 && num2 == 0 ) { alert ("被除数不能为0" ); return false ; } var result = cal (parseInt (num1), parseInt (num2), parseInt (type)); document .getElementById ("val" ).innerText = result; }; </script > </html >
补充代码如下:break; 这里的break是不必要的,因为return已经结束了函数的执行
1 2 3 4 5 6 7 8 9 10 11 12 13 14 function cal (num1, num2, type ) { switch (type){ case 0 : return num1 + num2 case 1 : return num1 - num2 case 2 : return num1 * num2 case 3 : return num1 / num2 } } module .exports = cal;
计算器 灯泡变色–定时器
页面加载完成 3 秒后灯的颜色变成红色。 在灯的颜色变成红色的 3 秒后,灯的颜色变成绿色(即 6 秒后灯光变成绿色)。 随后颜色不再变化。 请通过修改 display 属性来显示不同颜色的灯的图片
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 function red ( ) { document .getElementById ('defaultlight' ).style .display = 'none' ; document .getElementById ('greenlight' ).style .display = 'none' ; document .getElementById ('redlight' ).style .display = 'inline-block' ; } function green ( ) { document .getElementById ('defaultlight' ).style .display = 'none' ; document .getElementById ('redlight' ).style .display = 'none' ; document .getElementById ('greenlight' ).style .display = 'inline-block' ; } function trafficlights ( ) { setTimeout (red, 3000 ); setTimeout (green, 6000 ); } trafficlights ();
其他 fectch 购物狂欢节
要求:在 js/stores/useProducts.js 中补充 fetchProducts 函数, category 参数代表商品的分类。可能传来值为 books 、 clothing 、 electronics ,三个值对应的请求文件分别为 api/products/ 中 books.json 、 clothing.json 、 electronics.json 的数据,将请求到的数据赋值到 this.products 中(每次请求都要重新赋值,请求数据不累加),函数不需要返回值
使用 fetch(url) 发送请求。 使用 .json() 将响应体(res)解析为 JSON 数据。
1 2 3 4 5 6 function fetchProducts (category ) { fetch (`api/products/${category} .json` ) .then (res => {return res.json ()} ) .then (data => {this .products =data}) .catch (err => {console .log (err)}) }
1 2 3 function fetchProducts (category ) { const data = await ( await fetch (`api/products/${category} .json` )).json (); this .products =data
1 2 3 4 async function fetchProducts (category ) { products.value = await fetch (`./api/products/${category} .json` ).then (res => res.json ()) }
添加商品到购物车 1 2 3 4 5 6 7 8 9 function addProduct (product ) { if (products.value .includes (product)) { product.quantity ++; } else { product.quantity = 1 ; products.value .push (product); } }
计算总价 1 2 3 4 5 const totalPrice = computed (() => { var sum=products.value .reduce ((acc, cur ) => acc + (cur.price * cur.quantity ), 0 ) return sum });
axios 知识点统计图–axios
请在 TODO 1 处使用 axios 完成题库数据请求,请求地址储存在 mockUrl 变量中,将请求到的数据以 js 数组对象的形式储存在 rawData 变量中。并将 rawData 变量值传递给函数 extractUniquePoints,最终将函数 extractUniquePoints 的执行结果赋值给变量 knowledgePoints。
1 2 3 4 5 6 7 8 onMounted (function ( ) { chart = echarts.init (chartContainer.value ); axios.get (mockUrl).then ((res )=> rawData.value = res.data ) knowledgePoints= extractUniquePoints (rawData.value ) });
学生探览–axios获取数据并保存给items 在 TODO1 处使用 AXIOS 请求班级数据,并储存到变量items中 数据地址已经储存在变量 mockUrl 中,请直接使用此变量作为请求地址
1 2 3 4 5 6 7 8 9 axios.get (mockUrl).then ((res )=> { items.value =res.data }).catch ((err )=> { console .log (err); }) }
学生探览–计算属性,数组 TODO2 处补全代码,当对班级学生信息进行查询时会触发。根据班级数据(即目标 1 获取赋值的 items 变量)分别计算班级在“技术能力得分”、“硬实力得分”、“软技能得分”三个方面的平均成绩,并将这三个方面的平均成绩以数组的方式赋值到计算属性 classAverageScores 中。
1 2 3 4 5 6 const classAverageScores = computed (()=> items.value .reduce ((acc,cur,_ )=> { return cur.scores .map ((item,index )=> acc[index]+item) },[0 ,0 ,0 ]).map (score =>Math .round (score/items.value .length )) )
Echarts 1 2 3 4 5 6 7 8 9 10 11 radar : { shape :'circle' , startAngle :0 , indicator : [ { name : "技术能力得分" , max : 100 , min : 0 }, { name : "硬实力得分" , max : 100 , min : 0 }, { name : "软技能得分" , max : 100 , min : 0 }, ], },
日期 每日签到 1 2 3 4 5 6 7 signInBtn.addEventListener ("click" ,()=> { let days=document .querySelectorAll ("#days p" ) let day=new Date ().getDate () days[day-1 ].classList .add ("active" ) document .querySelector ("#sign_in_btn" ).classList .add ("no-active" ) document .querySelector ("#sign_in_btn" ).innerText ="明天也要记得来哦" })
浏览器 你还在等我吗
补充函数 setItem,当点击页面上「点击存入」按钮时,会调用此函数,并将存入键、存入值、存入有效毫秒时长这三个数据传入参数 key 、value 、expired 。补全代码,使函数根据key 和value 存入 localStorage 。 补充函数 getItem,当点击页面上「点击取出」按钮时,会调用此函数,并将要取值的键传入参数 key。补全代码,使函数根据 key 值从 localStorage 中取出数据并返回,如果数据超过有效毫秒时长,则清除数据。
补充函数 removeItem,当点击页面上「点击进行清理」按钮时,会调用此函数,并将要清理的键传入参数 key。补全代码,使函数根据 key 值从 localStorage 中清除数据。
1 2 3 4 5 6 7 8 9 10 11 12 class Storage { setItem (key, value, expired ) { localStorage .setItem (key, value) setTimeout (() => this .removeItem (key), expired) } getItem (key ) { return localStorage .getItem (key) } removeItem (key ) { localStorage .removeItem (key) } }
小结 getAttribute 的作用:获取 HTML 元素的指定属性值const name1=trigger.getAttribute("data-filter-name")
媒体查询
1 2 3 @media screen and (max-width :760 ox){屏幕宽度<760 时生效 }
旋转角度`transform: rotate(60deg)`
新增元素添加样式再插入
1 2 3 const xz = createElement('span ') xz.style .xxx =xxx oldelement.append (xz) //(弹幕那道题)
对象变数组拼接
1 2 const arr1 = Object .keys (要处理的对象).map (item => item+"=" 要处理的对象[item]).join ("$" )const arr2 = Object .entires (要处理的对象).map (([key,value] )=> key+"=" +value).join ("&" )
有没有包含+三目运算符 arr.includes(“包含的东西”) ? 包含了执行 : 没包含执行 ref声明的对象数组操作,别丢value!! 原题
1 2 3 4 5 const waste = ref ([{k1 :v1,k2 :v2,k3 :v3},{},{}])waste.value .forEach (item => {if (item.k1 ==='厨余垃圾' ){ food_waste.value .push (item.k2 ) } })