凭空消失的TA
题解
加入第二行代码即可,没有使用elementUI提供的js文件,所以说提供的所有文件都是有用的呀~
<!-- 引入 element-ui 样式 -->
<link rel="stylesheet" href="./element-ui-2.15.10/index.css" />
<script src="./element-ui-2.15.10/index.js"></script>
用户名片
题解
核心就是让整个卡片无论在什么时候都是页面居中,就是无论你缩放页面总是居中。这里就必须用到最后的center样式
* {
margin: 0;
padding: 0;
}
html,
body {
background: #fceeb5;
height: 100%;
overflow: hidden;
}
html,
body {
background: #fceeb5;
}
.card {
width: 450px;
height: 250px;
background: #fff;
box-shadow: 0 8px 16px -8px rgba(0, 0, 0, 0.4);
border-radius: 6px;
overflow: hidden;
position: absolute;
margin: auto;
left: 0px;
bottom: 0;
top: 0;
right: 0;
}
.card h1 {
text-align: center;
}
.card img {
width: 110px;
height: 110px;
border-radius: 50%;
}
.additional {
position: absolute;
height: 100%;
background: #92bca6;
z-index: 2;
}
.user-card {
width: 150px;
height: 100%;
position: relative;
float: left;
}
.user-card .points {
top: 85%;
}
.general {
width: 300px;
height: 100%;
position: absolute;
top: 0;
right: 0;
z-index: 1;
box-sizing: border-box;
padding: 12px;
padding-top: 0;
display: flex;
flex-flow: column;
justify-content: space-around;
}
.more{
display: block;
text-align: right;
}
/* level 和 points 定位位置 */
.level,
.points {
width: 72px;
text-align: center;
position: absolute;
color: #fff;
font-size: 12px;
font-weight: bold;
background: rgba(0, 0, 0, 0.15);
padding: 2px 0;
border-radius: 100px;
white-space: nowrap;
/*这里改了一下*/
bottom: 5% !important;
}
/* level 位置这里也改了一下 */
.level {
top: -68% !important;
height: 15px;
}
/* TODO 待补充代码 居中样式*/
.center{
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
margin: auto;
}
芝麻开门
题解
需要注意的是得把点击确定按钮的事件放在promise中,以至于最终返回的是mPrompt()的状态,不然放在外面返回的就是点击事件的状态了。我就是犯了这个错误,然后答案一直不对。然后点击事件用了.onclick和addEventListener事件监听器,因为开始不太熟悉还是什么都要多用用
const incantations = "芝麻开门";
function init(el) {
document.querySelector(".wrapper .btn").addEventListener("click", () => {
mPrompt()
.then((res) => {
console.log("@@@@@@@@@@" + res);
if (res === incantations) {
document
.querySelectorAll("#door .doors")[0]
.classList.add("door-left");
document
.querySelectorAll("#door .doors")[1]
.classList.add("door-right");
}
})
.catch((err) => {
console.log(err);
});
});
}
/**
* @description: 调用函数,开启弹窗,记录输入框的内容,并通过 promise 异步返回输入框中的内容
* @return {Promise}
*/
function mPrompt() {
// 弹窗必须使用以下结构 template 保存的是弹窗的结构字符串,可以先转化为 DOM 再通过 appendChild 方式插入到 body 中
const template = `
<div class="modal">
<div class="message-box">
<div class="message-header">请输入咒语</div>
<div class="message-body">
<input type="text">
</div>
<div class="message-footer">
<button class="btn btn-small" id='cancel'>取消</button>
<button class="btn btn-small btn-primary" id='confirm'>确定</button>
</div>
</div>
</div>
`;
// 让对话框弹出,先创建子节点
const dialogDiv = document.createElement("div");
dialogDiv.innerHTML = template;
// body元素最后追加一个div元素
let body = document.querySelector('body');
body.appendChild(dialogDiv);
// 获取对话框的确定和取消按钮,通过这个来操作对话框的显示与隐藏
let confirmBtn = document.getElementById("confirm");
let cancelBtn = document.getElementById("cancel");
let inputVal = "";
// TODO:待补充代码
return new Promise((resolve, reject) => {
// 点击确定事件
confirmBtn.onclick = function () {
// 注意getElementsByTagName获取到的是数组,取第一个
inputVal = document.getElementsByTagName("input")[0].value
body.removeChild(dialogDiv)
if (inputVal == "芝麻开门") {
return resolve("芝麻开门")
} else {
return reject(false)
}
}
// 取消事件
cancelBtn.addEventListener("click", () => {
body.removeChild(dialogDiv)
reject(false)
})
})
}
宝贵的一票
总结
这个题还是比较简单的就是考察了简单点dom操作,但是犯了一点错误,就是最终一直没有评测成功,最后发现应该是我动了初始化函数initRender 最初的dom结构,我为了图方便直接在里面都加了那个叉号的dom,但是最后评测时是不能有叉号的dom元素存在的,虽然我使它的display为none了但是还是不能通过检测,提示只有第一次删除检测成功,后面的直到选项小于等于2时应该就失败了。因为它检测到了序列小于2时还存在删除按钮的dom结构。
写这些的目的就是告诉大家一定不要随便操作题目已经给出的dom结构,因为它的评判标准里面就应该会检测最终的dom结构。当然我这个也是有解决办法的,就是在最后判断选项长度小于等于2时直接把选项1和选项2的删除按钮的dom结构remove就ok啦~ 我是小辣鸡一起进步吧
题解
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<title>宝贵的一票</title>
<script src="./js/jquery.min.js"></script>
<link rel="stylesheet" href="./css/bootstrap.min.css" />
<link rel="stylesheet" href="./css/style.css" />
</head>
<body>
<div class="inner-container shadow">
<div class="mb-3 row">
<label class="col-sm-2 col-form-label">投票主题</label>
<div class="col-sm-9">
<input type="text" class="form-control" />
</div>
</div>
<div class="list"></div>
<div class="add">
<div class="addtxt">
<img src="./images/plus-square.svg" alt="加号图标" />
添加选项
</div>
</div>
<div class="form-check checkbox-one">
<input class="form-check-input" type="checkbox" value="" />
<label class="form-check-label" for="flexCheckDefault">
支持多选
</label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" value="" />
<label class="form-check-label" for="flexCheckDefault">
公开投票结果
</label>
</div>
<div class="row bottom">
<div class="col">
<a class="historytxt" href="javascript:void(0)">历史投票</a>
</div>
<div class="col"></div>
<div class="col">
<button type="button" class="btn btn-light">取消</button>
<button type="button" class="btn btn-primary">发起投票</button>
</div>
</div>
</div>
<script>
let initRender = (txt) => {
return `<div class="mb-3 row" >
<label class="col-sm-2 col-form-label txt">${txt}</label>
<div class="col-sm-9">
<input type="text" class="form-control">
</div>
<div class="col-sm-1">
<!-- 删除图标 -->
<img class="del-icon" src="./images/x.svg" alt="" style="display:none" />
</div>
</div>`;
};
$(
(function () {
// 初始化的时候渲染两条数据,且不带删除符号
for (let index = 0; index < 2; index++) {
let initList = initRender(`选项${index + 1}`);
$(".list").append(initList);
}
// 点击加号逻辑
$(".add").click(function () {
// TODO 待补充代码
// 获取当前选项列表的长度,根据initRender函数中的模板字符串可得到灵感
let listLength = $('.list .row').length;
let initList = initRender(`选项${listLength + 1}`);
$(".list").append(initList);
console.log(listLength);
if (listLength >= 2) {
$('.del-icon').css("display", "block")
}
});
// 点击 x 删除逻辑,列表小于 2 项时不显示删除图标
$(document).on("click", ".del-icon", function () {
// TODO 待补充代码
// console.log($(this).parent().parent());等价于$(this).parents()[1]
$(this).parents()[1].remove()
let listLength = $('.list .row').length;
for (let index = 0; index < listLength; index++) {
$('.txt')[index].innerHTML=`选项${index+1}`
}
console.log(listLength);
if (listLength> 2) {
$('.del-icon').css("display", "block")
}else{
$('.del-icon').css("display", "none")
// 切记要删除这里呀,因为判题应该是根据dom结构来滴
$('.list .col-sm-1').remove()
}
});
})()
);
</script>
</body>
</html>
粒粒皆辛苦
思路:
- 先直接看json文件中的数据格式,看到是一个对象中嵌套对象的格式。获取数据就好
- 一般echarts题都有初始化渲染的例子,
我们不要动
,然后直接看它是怎么渲染的,照着写就行。
获取到数据后对数据进行处理,我是直接使用for of 对对象进行遍历然后将里面不同类型的值进行分类- 直接修改 option.dataset.source中的值注意最前面要加上大豆,玉米啥的中文名。最后一定得调用
渲染函数myChart.setOption(option);
最终页面才会改变
题解
<!DOCTYPE html>
<html style="height: 100%">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<title>粒粒皆辛苦</title>
<script type="text/javascript" src="./js/echarts.min.js"></script>
<script src="./js/axios.min.js"></script>
</head>
<body style="height: 100%; margin: 0; overflow: hidden">
<div id="container" style="height: 80%; width: 80%; margin: 5% auto"></div>
<script>
var dom = document.getElementById("container");
var option;
var myChart = echarts.init(dom, null, {
renderer: "canvas",
useDirtyRect: false,
});
let initCharts = () => {
option = {
title: {
text: "近五年 x 市粮食总产量分布以及 2022 年粮食产量比例",
subtext: "单位(万吨)",
},
dataset: {
//source -> 图表显示所需的数据格式(饼形图和折线图共用),请勿手动修改此行
source: [
["全部", "2017", "2018", "2019", "2020", "2021", "2022"],
["小麦", 1, 1, 1, 1, 1, 1],
["大豆", 9, 9, 9, 9, 9, 9],
["马铃薯", 13, 13, 13, 13, 13, 13],
["玉米", 23, 23, 23, 23, 23, 23],
],
},
xAxis: { type: "category" },
yAxis: { gridIndex: 0 },
grid: { top: "55%" },
series: [
{
type: "line",
seriesLayoutBy: "row",
},
{
type: "line",
seriesLayoutBy: "row",
},
{
type: "line",
seriesLayoutBy: "row",
},
{
type: "line",
seriesLayoutBy: "row",
},
{
type: "pie",
id: "pie",
radius: "30%",
center: ["50%", "25%"],
label: {
// 2022 数据的百分比
formatter: "{b} {@2022} ({d}%)",
},
encode: {
itemName: "全部",
value: "2022",
tooltip: "2022",
},
},
],
};
if (option && typeof option === "object") {
// myChart.setOption -> 设置 echarts 数据的方法
myChart.setOption(option);
}
window.addEventListener("resize", myChart.resize);
};
initCharts();
// TODO: 待补充代码
var dataList = {}
// 初始化四个数组
var wheat = ["小麦"], soybean = ["大豆"], corn = ["玉米"], potato = ["马铃薯"]
window.onload = function () {
axios.get(' ./data.json')
.then(res => {
dataList = res.data.data;
// 双重循环取对象值
for (item in dataList) {
// console.log(dataList[item]);
let value = dataList[item]
for (subitem in value) {
// console.log(value[subitem]);
if (subitem === "wheat") {
wheat.push(value[subitem])
} else if (subitem === "soybean") {
soybean.push(value[subitem])
} else if (subitem === "corn") {
corn.push(value[subitem])
} else if (subitem === "potato") {
potato.push(value[subitem])
}
}
}
option.dataset.source = [
["全部", "2017", "2018", "2019", "2020", "2021", "2022"],
wheat,
soybean,
potato,
corn,]
myChart.setOption(option);
console.log(option);
})
}
</script>
</body>
</html>
618 活动
介绍
最近蓝桥准备了很多 618 优惠,今天我们将化身蓝桥前端小工,亲自动手制作一个 618 活动页面,快来一显身手吧。
后面补哈~~
资讯接口
题解
其实和模拟一的那个node题都是一样的原理
const http=require('http');
const server=http.createServer();
server.on('request',(req,res)=>{
// 设置请求头
res.setHeader("Content-type", "text/html;charset=utf8");
if(req.url=="/news"){
res.end(JSON.stringify(
[
{
"channelId": "5572a108b3cdc86cf39001cd",
"name": "国内焦点"
},
{
"channelId": "5572a108b3cdc86cf39001ce",
"name": "国际焦点"
}
]
))
}else{
res.end("404")
}
})
server.listen(8080,function(){
console.log("8080端口启动成功");
})
绝美宋词
题解
思路:使用v-model实现双向绑定,最后使用watch监听words的变化,最后需要使用v-html指令在展示经过我们处理的字符串
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>绝美宋词</title>
<link rel="stylesheet" href="css/style.css" />
<script src="./js/vue.min.js"></script>
<script src="./js/axios.min.js"></script>
</head>
<body>
<div id="app">
<h1 style="text-align: center">输入关键字,找一首词</h1>
<!-- TODO:待补充代码 -->
<div class="search-form">
<input type="text" id="search" v-model="words" class="search" placeholder="词牌名 词句 词人" />
<ul class="suggestions" v-if="">
<li v-for="item in resultList" :key="item.title">
<span class="poet" v-html="item.poetry_content"></span>
<span class="title" v-html=`${item.title}-${item.author}`></span>
</li>
</ul>
</div>
</div>
<script>
let vm = new Vue({
el: '#app',
// TODO:待补充代码
data() {
return ({
poetryList: [],//数据库数据
resultList: [],//最终展示数据
words: '' //关键字
})
},
mounted() {
axios.get('./data.json').then(res => {
this.poetryList = res.data
})
},
watch: {
words(newVal, oldVal) {
if (newVal === '') {
//如果关键字为空不匹配,直接返回
this.resultList = [];
return;
}
console.log("newVal值", newVal);
this.resultList = [];
this.poetryList.forEach(item => {
// 处理关键字,得到含有关键字的对象
if (item.poetry_content.includes(newVal) || item.title.includes(newVal) || item.author.includes(newVal)) {
// 注意这里得使用深拷贝,不然在下面重新赋值resultList时会改变原有的从JSON中的数据,
// 导致最终只能匹配一个字符
this.resultList.push(JSON.parse(JSON.stringify(item)))
}
})
// 处理高亮,全部的
let reg = new RegExp(newVal, 'g');
this.resultList.forEach(ele => {
// 关键字替换
ele.poetry_content = ele.poetry_content.replace(reg, `<span class="highlight">${newVal}</span>`)
ele.title = ele.title.replace(reg, `<span class="highlight">${newVal}</span>`)
ele.author = ele.author.replace(reg, `<span class="highlight">${newVal}</span>`);
})
},
}
})
</script>
</body>
</html>
平地起高楼
题解
这个题最开始我是想直接一遍又一片for循环的后来发现好像所有的流程都是一样的,就开始尝试使用递归,但是最开始的递归时所有的数据都是单独存在的,并没有什么联系,于是我就打开了控制台反复测试每一次递归的结果,发现的确每一次递归都是正确的,但是我设置的
resultList.children=convertToTree(regions, item.id)
并没有效果,导致所有的数据都无法关联,最后测试出了可以直接使用item.children,因为regions的数据是我们每一次递归都不会改变的,所以可以对其进行操作,保证最后的递归数据能够串联起来。
function convertToTree(regions, rootId = "0") {
// TODO: 在这里写入具体的实现逻辑
// 将平铺的结构转化为树状结构,并将 rootId 下的所有子节点数组返回
// 如果不存在 rootId 下的子节点,则返回一个空数组
let resultList=[];
// let testList=[]
regions.forEach(item=>{
// let testList=[];
if(item.pid===rootId){
// 符合结果就放进去,比如最先找到四川,然后就把四川
//放进去,之后在把四川作为pid去查找下一个子代。之后在遍历子代
resultList.push(item);
// testList=resultList
// 没用,因为每一次递归后的return的是resultList,所以最终会不断
//的改变,所以得使用item.children,直接改变它的值
//resultList.children=convertToTree(regions, item.id)
// 为孩子做准备,题目也说了如果没有孩子就设置为空数组,不影响
// item.children=[],这一次递归的结果就是找到这一轮符合要求的子代
//这里把item.id作为pid继续查找子代
item.children=convertToTree(regions, item.id)
// console.log(convertToTree(regions, item.id));
// resultList.children=convertToTree(regions, item.id);
// console.log(resultList);解开注释,观察递归效果
}
})
return resultList;
}
module.exports = convertToTree; // 检测需要,请勿删除
收快递了
最初错误示例
function findRegion(regions, regionName) {
// TODO: 在这里写入具体的实现逻辑
// 需要从树状结构的行政信息中,遍历找到目标区域的行政信息,如输入:成都市,返回 [四川省,成都市]
// 如果所输入的位置信息不存在,则返回 null
let replceList=regions[0];
// 省
let resultArr=[regions[0].name];
if(replceList.name===regionName){
return resultArr;
}
var flag1=false;
for(let i=0;i<replceList.children.length;i++){
// 市级
if(replceList.children[i].name===regionName){
resultArr.push(regionName)
flag1=true
break;
}else{
// 区级
replceList.children[i].children.forEach(item=>{
if(item.name===regionName){
flag1=true
resultArr.push(replceList.children[i].name)
resultArr.push(item.name)
}
})
}
}
if(flag1){
return resultArr;
}else{
return null;
}
}
module.exports = findRegion; // 检测需要,请勿删除
题解
检测发现原来是我最初的时候就把省份定死啦,我以为最后测试的数据只有一个省原来不是!!!所以在加一层循环就好啦!!!但是这样真的很消耗时间哦,幸好不是算法竞赛,不然就给我TTL了,真给我写麻了。
需要注意的是只有for循环或者while等其他循环语句才可以使用break,所以当我使用forEach时是没有使用break跳出的。
function findRegion(regions, regionName) {
// TODO: 在这里写入具体的实现逻辑
// 需要从树状结构的行政信息中,遍历找到目标区域的行政信息,如输入:成都市,返回 [四川省,成都市]
// 如果所输入的位置信息不存在,则返回 null
let resultArr=[]
var flag1 = false;//最终返回条件
for (let t = 0; t < regions.length; t++) {
// 省
if (regions[t].name === regionName) {
resultArr.push(regions[t].name)
flag1 = true;
break
} else {
for (let i = 0; i < regions[t].children.length; i++) {
// 市级
if (regions[t].children[i].name === regionName) {
resultArr.push(regions[t].name)
resultArr.push(regionName)
flag1 = true
break;
} else {
// 区级
regions[t].children[i].children.forEach(item => {
if (item.name === regionName) {
flag1 = true
resultArr.push(regions[t].name)
resultArr.push(regions[t].children[i].name)
resultArr.push(item.name)
}
})
}
}
}
}
if (flag1) {
return resultArr;
} else {
return null;
}
}
module.exports = findRegion; // 检测需要,请勿删除