题目链接:声网编程竞赛7月专场 - 蓝桥云课 (lanqiao.cn)
提要:题目中涉及到的知识点放在最后面了🙈🙈🙈……
第一题:让时钟转起来
知识点:Date对象

所以就还剩下秒针的旋转角度还没算,所以需要补充的代码就是秒针的旋转角度了。
因为一圈360度,一圈60秒。那么1s就转6deg。
我的答案:
oSecond.style.transform="rotate("+ (nowSecond * 6) + "deg)";
第二题:调皮的模态框
知识点:阻止事件冒泡

由上图可得它们是嵌套关系,所以当点击里面handleOk()函数,执行了此函数之后又执行了handleClick()事件,所以才导致你看到的那样handleOk事件设置的display为none无效。所以要在handleOk()阻止一下它向外冒泡。
我的答案:
<script>
// 请在这里补充代码,根据需求解决事件冒泡带来的问题,实现模态框的显隐操作。
let myModal = document.querySelector("#myModal")
function handleClick() {
myModal.style.display = 'block'
}
function handleOk() {
myModal.style.display = 'none'
event.stopPropagation()//阻止冒泡行为
}
</script>
第三题:由文本溢出引发的“不友好体验”
知识点:css属性:overflow、text-overflow、-webkit-line-clamp
我的答案:
<script>
// 请在下方补充代码,使得文本溢出 2 行时使用省略号
var more=document.querySelector('.more2_info_name')
more.style.overflow="hidden"
more.style.textOverflow="ellipsis"
more.style.webkitLineClamp=2;
</script>
第四题:下次“绕”过你
知识点:本地存储localStorage
利用localstorage将第一次通过接口获取到的数据存入本地,再次进来的时候如果本地存在数据就不需要再请求接口,直接从本地拿数据完成页面展示。
<script>
// 请在修改或填补下方代码:
// 请实现:在请求数据之前,判断 localStorage 中是否存有名为 historyData 的数据;
// 1. 没有,则发送请求获取数据;2. 有,则从 localStorage 中获取。
var historyData=localStorage.getItem('historyData')
if(historyData){
renderhtml(JSON.parse(historyData))
}else{
// 请求数据,请勿删除
axios.get("https://labfile.oss.aliyuncs.com/courses/9203/historyData.json")
.then(res => {
if (res.status === 200) {
const {data} = res.data;
localStorage.setItem('historyData',JSON.stringify(data))
renderhtml(data)
}
})
}
// 将数据写入 HTML 模板,请勿删除
function renderhtml(data){
const html = `${data.map(function (item, index) {
return `
<div id="course-9203" class="course-item course-info" data-v-062d7aaa="">
<div data-v-3ba6c69d="" class="row">
<div data-v-3ba6c69d="" class="col-lg-4">
<div data-v-3ba6c69d="" class="course-img"><a data-v-3ba6c69d="" :href="item.href" class="block" target="_blank"><img data-v-3ba6c69d="" src="${item.imgSrc}" height="160" alt="${item.imgSrc}"></a> <span data-v-23ac173c="" data-v-3ba6c69d=""><span data-v-23ac173c=""></span></span></div>
</div>
<div data-v-3ba6c69d="" class="col-lg-6">
<div data-v-3d67ec2c="" data-v-3ba6c69d="" class="course-title"><span data-v-3d67ec2c="">
${item.title}
<span data-v-3d67ec2c="">
${item.last}
</span></div>
<div data-v-3ba6c69d="" class="course-related"><span data-v-3ba6c69d="">
${item.report}篇实验报告
<!----></span> <span data-v-3ba6c69d="">
${item.question}个提问
<!----></span></div>
</div>
<div data-v-3ba6c69d="" class="col">
<div data-v-4b66fd24="" data-v-3ba6c69d="" class="operate"><span data-v-4b66fd24="" class="operate-top"><span data-v-4b66fd24="" class="more"> 更多 </span> <span data-v-4b66fd24="" class="delete">
删除记录
</span></span> <a data-v-4b66fd24="" href="/courses/9203/learning" class="operate-bottom" target="_blank">
继续实验
</a>
</div>
</div>
</div>
</div>
`
}).join('')}`;
// 将 HTML 模板插入到元素中,请勿删除
document.querySelector('.container').innerHTML = html;
}
</script>
第五题:你能看出有多少位吗?
知识点:数字的千分位分隔功能。
//方法一
$('.form-edit .num').click(function(){
var oDiv = document.getElementById("input-box");
oDiv.innerHTML += this.innerHTML;
function numFormat(num){
var res=num.toString().replace(/\d+/, function(n){ // 先提取整数部分
return n.replace(/(\d)(?=(\d{3})+$)/g,function($1){
return $1+",";
});
})
return res;
}
oDiv.innerHTML=numFormat(oDiv.innerHTML.replaceAll(',',''))
})
//方法二
//有一个问题值不能输太大,太大会变成NaN。但是可以通过检测
oDiv.innerHTML=Number(oDiv.innerHTML.replace(',','')).toLocaleString()
第六题:为图片添加景深效果
这题主要是通过开发者工具发现图片上共同绑定了一个属性filter,才导致图片模糊的。

根据题目要求,我们只需要给枫叶林和人物单独设置一个样式将filter值设置为blur(0px)就不模糊了。
<script>
// 请在这里编写代码,根据需求,使得图片达到景深效果
var imgs=document.querySelectorAll('img')
imgs[0].style.filter="blur(0px)"
imgs[1].style.filter="blur(0px)"
</script>
第七题:验证密码强度
题目要求:

知识点:正则表达式
根据题目要求写if……else语句。
我的答案:
<script>
// 请在这里补充代码,实现密码强度的验证
var result=document.querySelector('.result')
var password=document.querySelector('.form-control')
var btn=document.querySelector('.btn-validate')
//表示至少需要一个小写字母和至少需要一个数字
var reg=new RegExp(/(?=.*[a-z])(?=.*[0-9]){9,}/g)
//表示至少需要一个大写字母和至少需要一个特殊字符
var reg1=new RegExp(/(?=.*[A-Z])(?=.*[^(0-9a-zA-Z)]){9,}/g)
btn.addEventListener('click',function(){
if(password.value.length<=8){
result.innerHTML='无效'
}else{
if(reg.test(password.value)){
if(reg1.test(password.value)){
result.innerHTML='高'
}else{
result.innerHTML='中'
}
}else{
result.innerHTML='低'
}
}
})
</script>
第八题:时间转换工具
日期可以转换成时间戳,时间戳可以转换为日期。
知识点:toLocaleString()、Date对象

问题1:使用new Date(time)或者moment(time)时,有时会出现Invalid Date报错。
解决办法:对时间戳进行处理。*1000就可以了。

问题2:对时间戳进行赋值时错误。
解决办法:将它赋值的时候再/1000就正常了。
我的答案:
//方法一
methods: {
handleTransform(){
if(this.formInline.date== ''){
let date = new Date(Number(this.formInline.timeStamp))
//转换为时间
this.formInline.date = date.toLocaleString()
}else{
//转换为时间戳
this.formInline.timeStamp = this.formInline.date.getTime()
}
}
}
//方法二
methods: {
handleTransform(){
if(this.formInline.date!=''){
//日期时间转换为时间戳
this.formInline.timeStamp=this.formInline.date.getTime()
}else{
//时间戳转换成日期时间
var time=new Date(1000*this.formInline.timeStamp)
this.formInline.date=time/1000
}
}
}
第九题:表格数据转换
题目要求:

考点:axios、foreach、replace、三目运算符、正则表达式
<script>
new Vue({
el: '#app',
data: function() {
return {
tableData: [],
}
},
mounted() {
axios.get('./fetchTableData.json').then((res)=>{
res.data.data.forEach(element => {
element.datetime=element.datetime.replace(/^(\d{4})(\d{2})(\d{2})$/, "$1-$2-$3")
element.sex===0?element.sex="女":element.sex="男"
element.vip===0?element.vip="否":element.vip="是"
});
this.tableData=res.data.data
})
},
methods: {
}
})
</script>
第十题:URL 参数解析并高亮文本内容
知识点:indexOf、forEach、replace、slice、regexp
将内容中出现key的地方,将key用<em></em>标签包裹实现高亮文本内容。
我的答案:
//方法一
<script>
// 请你在 script 标签中编写代码,实现根据 URL 中的关键字为内容中包含关键字的文本添加 em 标签,以表示高亮。
var search=document.querySelector('.search-box')
var input=document.querySelector('.input-box input')
var titles=document.querySelectorAll('.c-title')
var contents=document.querySelectorAll('.content-right')
search.addEventListener('click',function(){
var key=input.value.slice(input.value.indexOf('wd=')+3,input.value.indexOf('&d'))
if(key!=""){
titles.forEach((title)=>{
title.innerHTML=title.innerHTML.replaceAll('<em>','').replaceAll('</em>','')
if(title.innerHTML.indexOf(key)!==-1){
title.innerHTML=title.innerHTML.replaceAll(key,'<em>'+key+'</em>')
}else{
title.innerHTML=title.innerHTML.replaceAll('<em>','').replaceAll('</em>','')
}
})
contents.forEach((content)=>{
content.innerHTML=content.innerHTML.replaceAll('<em>','').replaceAll('</em>','')
if(content.innerHTML.indexOf(key)!==-1){
content.innerHTML=content.innerHTML.replaceAll(key,'<em>'+key+'</em>')
}else{
content.innerHTML=content.innerHTML.replaceAll('<em>','').replaceAll('</em>','')
}
})
}else{
titles.forEach((title)=>{
title.innerHTML=title.innerHTML.replaceAll('<em>','').replaceAll('</em>','')
})
contents.forEach((content)=>{
content.innerHTML=content.innerHTML.replaceAll('<em>','').replaceAll('</em>','')
})
}
})
</script>
//方法二
<script>
// 请你在 script 标签中编写代码,实现根据 URL 中的关键字为内容中包含关键字的文本添加 em 标签,以表示高亮。
// 搜索按钮
var search=document.querySelector('.search-box')
var inputBox=document.querySelector('.input-box input')
var mains=document.querySelector('.main-container')
//先存一次最开始的状态
var content=mains.innerHTML
search.addEventListener('click',function(){
var key=inputBox.value.slice(inputBox.value.indexOf('wd=')+3,inputBox.value.indexOf('&d'))
if(key!=0){
//每次进行查找前先置为初始状态
mains.innerHTML=content
mains.innerHTML=mains.innerHTML.replaceAll(key,`<em>${key}</em>`)
}else{
//key为空时置为初始状态
mains.innerHTML=content
}
})
</script>
知识点
1️⃣Date对象
<!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>Document</title>
</head>
<body>
<script>
//实例化时刻的日期和时间
var time=new Date()// Thu Mar 23 2023 08:55:33 GMT+0800 (中国标准时间)
// console.log(time)
//创建一个指定的日期对象
//字符串格式 月/日/年 时:分:秒 或者 年-月-日T时:分:秒
var time1=new Date("10/20/1998 12:22:23")//Tue Oct 20 1998 12:22:23 GMT+0800 (中国标准时间)
// console.log(time1)
//new Date(年,月,日,时, 分, 秒)
var time2=new Date(2016,0,1,13,45,33)//Fri Jan 01 2016 13:45:33 GMT+0800 (中国标准时间)
// console.log(time2)
//传一个时间戳
var time3=new Date(1679534390352)//Thu Mar 23 2023 09:19:50 GMT+0800 (中国标准时间)
// console.log(time3)
//获取当前时间戳
var time4=Date.now()
// console.log(time4)
//result=time.getFullYear() //返回四位的年份
//result=time.getMonth() //返回月份的索引 月份索引0~11分别表示1月~12月
//result=time.getDate() //返回当前是几号
//result=time.getDay() //返回当前日期是周几(0-6)0表示周日
//result=time.getTime() //返回当前时间的时间戳
//result=time.getHours() //返回一个指定的日期对象的时针数
//result=time.getMinutes() //返回一个指定的日期对象的分针数
result=time.getSeconds() //返回一个指定的日期对象的秒数
console.log(result)
</script>
</body>
</html>
2️⃣toLocaleString()
<script>
// toLocaleString() 返回一个字符串
//日期对象
var date=new Date()
console.log(date.toLocaleString()) //2023/3/23 下午4:39:10
//数组
var arr =[1,2,3,4];
console.log( arr.toLocaleString()) //1,2,3,4
//数值
var number=12345678901
console.log(number.toLocaleString()) //12,345,678,901
</script>
3️⃣本地存储和会话存储
本地存储和会话存储的区别:localStorage 的生命周期是永久的,除非用户清除 localStorage 信息,否则这些信息将永远存在。而sessionStorage 的生命周期是临时的,一旦当前窗口或标签页被关闭了,那么通过它存储的数据也就被清空了。
设置和获取Storage数据
//设置 key是自定义属性的名字 data是你要传入的数据
localStorage.setItem(key,data)
sessionStorage.setItem(key,data)
//获取
localStorage.getItem(key)
sessionStorage.getItem(key)
删除
//删除指定值
localStorage.removeItem(key)
sessionStorage.removeItem(key)
//删除所有
localStorage.clear()
sessionStorage.clear()
4️⃣replace
①字符串对象的replace方法可以替换匹配的值。它接受两个参数,第一个是要查找的字符,表示搜索模式,第二个是替换的内容。
②字符串对象的replace方法可以替换匹配的值。它接受两个参数,第一个是正则表达式,表示搜索模式,第二个是替换的内容。
③replace方法的第二个参数可以使用美元符号$,用来指代所替换的内容。
$&:插入匹配的子串。
$:插入当前匹配的子串左边的内容。
$':插入当前匹配的子串右边的内容。
$n:匹配成功的第n组内容,n是从1开始的自然数。
$$:插入一个 $。
//使用$1~$n可以对数据格式进行处理
data=“20220502”
data.replace(/^(\d{4})(\d{2})(\d{2})$/, "$1-$2-$3") //返回的格式2022-05-02
④replace方法的第二个参数还可以是一个函数,将每一个匹配内容替换为函数返回值。
5️⃣正则表达式
匹配规则
字面量字符
/hello/.test('hello,word!!!')//true hello就是字面量字符,表示文本hello,word!!!中包含hello。
元字符包括:.、^、$、| 、\、*、+、?、()、[]、{}
//点运算符(.)
//.表示任意一个字符 表示匹配c和t之前包含任意一个字符的清空。
/c.t/
//位置字符(^)($)
//^ 表示字符串的开始位置 $表示字符串的结束位置
/^test/.test('test123') //以test开头的返回true
/test$/.test('123 test') //以test结尾的返回true
/^test$/.test('test') //开始到结尾只有test的返回true
//选择符(|)
// | 表示或关系
/11|22|33/.test('hjh11jk') //表示再字符串中有11、22、33其中一个就返回true
//字符类 [] 表示有一系列字符可选择只要匹配其中一个就可以。
/[abc]/.test('apple') //true 表示在a,b,c之中任选一个。
//脱字符(^):表示除了字符类之中的字符 ,只能在[]中使用。
/[^abc]/ //表示除了a,b,c之外的所有字符都可以匹配
//连字符(-):表示字符的连续范围,只能在[]中使用。。
/[a-z]/ //表示26个小写字母
/[a-zA-z]/ //就表示所有的字母
//重复类 {} 模式的精确匹配次数{n,m}表示重复不少于n次,不多于m次
/lo{2,5}k/.test('looook')//表示o至少出现2到5次返回true
//量词符 ? * +
//? 问号表示某个模式出现0次或1次,等同于{0,1}
//* 星号表示某个模式出现0次或多次,等同于{0,}
//+ 加号表示某个模式出现1次或多次,等同于{1,}
特殊字符

转义字符

预定义模式
\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]。
\b 匹配词的边界。
\B 匹配非词边界,即在词的内部。
修饰符
g 修饰符
默认情况下,第一次匹配成功后,正则对象就停止向下匹配了。g修饰符表示全局匹配(global),加上它以后,正则对象将匹配全部符合条件的结果,主要用于搜索和替换。
var regex = /b/g;
i 修饰符
默认情况下,正则对象区分字母的大小写,加上i修饰符以后表示忽略大小写。写法和上面一样。
m 修饰符
//1.上面的代码中,字符串结尾处有一个换行符。如果不加m修饰符,匹配不成功,因为字符串的结尾不是world;加上以后,$可以匹配行尾。
/world$/.test('hello world\n') // false
/world$/m.test('hello world\n') // true
//2.上面代码要求匹配行首的b,如果不加m修饰符,就相当于b只能处在字符串的开始处。加上m修饰符以后,换行符\n也会被认为是一行的开始。
/^b/m.test('a\nb') // true
6️⃣CSS属性filter
用途:可以对图片进行模糊或颜色偏移等变化。
/*blur()用于设置图片模糊程度*/
filter:blur(5px);
/*brightness()用于设置图片亮度 默认为1,>100%会变量,<100%会变暗*/
filter: brightness(0.4);
/*contrast用于设置图片对比度 100%为正常*/
filter: contrast(50%);
/*drop-shadow()用于设置图片阴影 offset-X offset-y [blur] [color] 第三个值用于设置模糊*/
filter: drop-shadow(16px 16px 20px blue);
/*grayscale()用于设置图片灰度 0%~100% 0为无变化*/
filter: grayscale(60%);
/*hue-rotate()函数在输入图像上应用色相旋转。*/
filter: hue-rotate(90deg);
/*invert()函数反转输入图像*/
filter: invert(75%);
/*opacity()用于设置图片透明度*/
filter: opacity(25%);
/*saturate()设置图像饱和度*/
filter: saturate(30%);
/*sepia()将图像转换为深褐色*/
filter: sepia(60%);
🌷结语
有些内容写的可能没那么清楚,例如replace那块,我对于$使用方法上还存在一些疑惑所以写的没那么清楚,请多包容。有问题的地方,请各位大佬帮忙指正!!!