持续更新中......
第一题:元素周期表
/* TODO 待补充代码 Start*/.container .table { /* 请使用 flex布局,使元素周期表中的 18 列元素横向排列。 */ display: flex;}.container .table .interval1 { /* 请使用 var、calc 函数设置第2、13~17列元素(class=interval1)的 margin-top 为 1 个元素的高度 */ margin-top: var(--interval);}.container .table .interval3 { /* 设置第3~12列元素(class=interval3)的 margin-top 为 3 个元素的高度。 */ margin-top: calc(var(--interval) * 3);}/* TODO End */
第二题:每日签到
// TODO:请补充代码// 为每日签到按钮(id="sign_in_btn")绑定一个点击事件signInBtn.addEventListener("click", () => { // let currentAllDate = new Date().toISOString().split("T")[0]; 2024-11-23 let currentDate = new Date().getDate(); let paragraphs = daysBox.querySelectorAll("p"); let foundFlag = false; // 实现在天数元素(id="days")下,为当前系统时间的日期相同的 p 标签添加一个 active 类,表示签到成功 for (let i = 0; i < paragraphs.length; i++) { if (paragraphs[i].textContent == currentDate) { paragraphs[i].classList.add("active"); foundFlag = true; break; } } // 为每日签到按钮(id="sign_in_btn")添加一个 no-active 类,表示按钮不可用,并将提示文字改为:明天也要记得来哦 if (foundFlag) { signInBtn.classList.add("no-active"); signInBtn.innerHTML = "明天也要记得来哦"; }});
第三题:你还在等我吗
class Storage { constructor() { this.storage = window.localStorage; } setItem(key, value, expired) { // TODO 待补充代码 window.localStorage.setItem(key, value); setTimeout(() => { delete window.localStorage[key]; }, expired); } getItem(key) { // TODO 待补充代码 return window.localStorage[key] || null; } removeItem(key) { // TODO 待补充代码 setbox.textContent = ""; getbox.textContent = ""; delete window.localStorage[key]; }} const storage = new Storage(); // 为了检测时使用,请勿删除if (window) { window.storage = storage;}
第四题:地址识别
function parseContactInfo(text) { // TODO: 请补充代码 // 定义正则表达式 let nameRegex = /[\u4e00-\u9fa5]{2,4}/; let phoneRegex = /\d{11}/; let addressRegex = /^[\u4e00-\u9fa5][\u4e00-\u9fa5a-zA-Z0-9]{3,}$/; // 分割输入文本 let parts = text.split(" "); // 初始化结果对象 const result = { name: "", phone: "", address: "", }; // 遍历每个部分,尝试匹配 parts.forEach((part) => { if (part.length >= 2 && part.length < 4 && nameRegex.test(part)) { result.name = part; } else if (part.length == 11 && phoneRegex.test(part)) { result.phone = part; } else if (part.length >= 4 && addressRegex.test(part)) { result.address = part; } }); return result;}
第五题:文本自动生成器
/** * 组合多个中间件函数,形成一个新的中间件函数。 * @param {...Function} middlewares - 要组合的中间件函数。 * @return {Function} - 组合后的中间件函数。 */function compose(...middlewares) { // TODO : 待补充代码 // 返回一个新的中间件函数 return function (initialValue, callback) { // 定义一个递归函数来依次执行中间件 const dispatch = (index, value) => { // 如果已经到达最后一个中间件,则执行 callback if (index === middlewares.length) { return callback(value); } // 获取当前中间件函数 const middleware = middlewares[index]; // 调用当前中间件函数,并传递当前值和下一个中间件函数 middleware(value, (nextValue) => { dispatch(index + 1, nextValue); }); }; // 开始执行第一个中间件函数 dispatch(0, initialValue); };}
第六题:静态文件服务
const fs = require("fs");const path = require("path");// 根据文件扩展名返回相应的 MIME 类型function getContentType(filePath) { const ext = path.extname(filePath).toLowerCase(); const contentTypeMap = { ".html": "text/html", ".css": "text/css", ".js": "application/javascript", ".png": "image/png", // 在这里添加其他文件类型及其对应的 MIME 类型 }; return contentTypeMap[ext] || "application/octet-stream";}// 递归遍历目录并生成文件映射表function generateStaticFilesMap(dir) { // 初始化文件映射表 const fileMap = {}; // 定义一个辅助函数来遍历目录 function traverseDir(currentDirPath) { // 读取当前目录中的所有文件和子目录 const entries = fs.readdirSync(currentDirPath); // 遍历每个条目 entries.forEach((entryName) => { // 获取当前条目的完整路径 const fullPath = path.join(currentDirPath, entryName); // 获取当前条目的状态(是文件还是目录) const entryStat = fs.statSync(fullPath); if (entryStat.isFile()) { // 如果是文件,添加到映射表 // 获取相对于根目录的路径 const relativePath = path.relative(dir, fullPath); // 将相对路径转换为以斜杠开头的 URL 路径 const urlPath = `/${relativePath}`; // 添加文件信息到映射表 fileMap[urlPath] = { filePath: fullPath, // 文件的完整路径 contentType: getContentType(fullPath), // 文件的内容类型 }; } else if (entryStat.isDirectory()) { // 如果是目录,则递归遍历 traverseDir(fullPath); } }); } // 从给定的根目录开始遍历 traverseDir(dir); // 返回生成的文件映射表 return fileMap;}// 使该函数可以被其他模块引用module.exports = generateStaticFilesMap;
第七题:企业微信会议助手
目标一:
const fetchMeetingData = async () => { // TODO: 待补充代码 return await fetch("js/meetings.json") .then((response) => { if (!response.ok) { throw new Error("网络响应错误"); } return response.json(); }) .then((data) => { meeting.value = { title: data.title, time: data.time, location: data.location, }; participants.value = data.participants; }) .catch((error) => { console.error("请求失败:", error); }); }; const formatDate = (dateStr) => { // TODO: 待补充代码 const date = new Date(dateStr); const year = date.getFullYear(); const month = String(date.getMonth() + 1).padStart(2, "0"); const day = String(date.getDate()).padStart(2, "0"); return `${year}-${month}-${day}`; };
目标二 :
const statusClass = (status) => { // TODO: 待补充代码 switch (status) { case "待确认": return "status-pending"; case "已接受": return "status-ready"; case "已拒绝": return "status-declined"; default: return "unknown"; } };
目标三:
function myAllSettled(promises) { // TODO: 待补充代码 // 不能使用 Promise.allSettled, Promise.all,Promise.race 等方法 const results = []; let completed = 0; return new Promise((resolve) => { promises.forEach((promise, index) => { promise .then( (value) => { results[index] = { status: "fulfilled", value }; }, (reason) => { results[index] = { status: "rejected", reason }; } ) .finally(() => { completed++; if (completed === promises.length) { resolve(results); } }); }); });}
第八题:知识点统计图
import { ref, onMounted, computed, reactive } from "vue";export default { setup() { const mockUrl = "./mock/question_bank.json"; let knowledgePoints = []; const chartContainer = ref(), rawData = ref([]); const difficultyOptions = ["简单", "中等", "困难"]; const progressOptions = [ "选题待审核", "题目制作中", "题目待测试", "题目待修改", "题目完成", ]; const filterObj = reactive({ difficulty: "", progress: "", }); //检测需要,请勿修改 Start window.setKnowledgePoints = function (data) { knowledgePoints = data; applyFilter(); }; window.getRawData = function () { return JSON.stringify(rawData.value); }; window.setFilter = function (d, p) { filterObj.difficulty = d; filterObj.progress = p; applyFilter(); }; window.getExtractUniquePoints = function (data) { return extractUniquePoints(data); }; //检测需要,请勿修改 End let chart; function applyFilter() { let data; // TODO 4 请在下面补充代码 let filteredData = rawData.value.filter((item) => { return ( (!filterObj.difficulty || item.difficulty === filterObj.difficulty) && (!filterObj.progress || item.progress === filterObj.progress) ); }); // 初始化 data 数组,长度为 knowledgePoints 的长度,初始值为 0 data = new Array(knowledgePoints.length).fill(0); // 遍历筛选后的数据,计算每个知识点的题目数量 filteredData.forEach((item) => { if (item.points && Array.isArray(item.points)) { item.points.forEach((point) => { const index = knowledgePoints.indexOf(point); if (index !== -1) { data[index]++; } }); } }); window.filteredData = JSON.stringify(data); // TODO 4 END const option = { title: { text: "知识点统计图", }, tooltip: { // TODO 6 请在下面补充代码 trigger: "item", axisPointer: { type: "none", }, valueFormatter: function (value, index) { return `${value} 个项目`; }, // TODO 6 END }, xAxis: { type: "category", axisLabel: { interval: 0, }, data: knowledgePoints, }, yAxis: { type: "value", }, series: [ // TODO 5 请在下面补充代码 { type: "bar", data: data }, // TODO 5 END ], }; window.chartData = JSON.stringify(option); // TODO 3 请在下面补充代码 // 使用 chart 变量来设置图表选项并渲染图表 chart.setOption(option); // TODO 3 END } function extractUniquePoints(data) { // TODO 2 请在下面补充代码 const pointsSet = new Set(); data.forEach((item) => { if (item.points && Array.isArray(item.points)) { item.points.forEach((point) => { pointsSet.add(point); }); } }); return Array.from(pointsSet); // TODO 2 END } onMounted(async function () { chart = echarts.init(chartContainer.value); // TODO 1 请在下面补充代码 try { const response = await axios.get(mockUrl); rawData.value = response.data; knowledgePoints = extractUniquePoints(response.data); applyFilter(); } catch (error) { console.error("获取数据失败:", error); } // TODO 1 END }); return { chartContainer, difficultyOptions, progressOptions, filterObj, applyFilter, }; }, template: `<div class="window"> <main ref="chartContainer"></main> <aside> <h2>筛选数据</h2> <el-form label-width="auto"> <el-form-item label="题目难度"> <el-select placeholder="选择要显示的题目难度" v-model="filterObj.difficulty"> <el-option v-for="(it, idx) in difficultyOptions" :key="idx" :value="it">{{ it }}</el-option> </el-select> </el-form-item> <el-form-item label="题目制作进度"> <el-select placeholder="选择要显示的题目制作进度" v-model="filterObj.progress"> <el-option v-for="(it, idx) in progressOptions" :key="idx" :value="it">{{ it }}</el-option> </el-select> </el-form-item> <el-form-item> <el-button type="primary" @click="applyFilter">应用筛选</el-button> </el-form-item> </el-form> </aside></div>`,};
第九题:西游净霸
<!DOCTYPE html><html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>西游争霸</title> <link rel="stylesheet/less" href="./css/style.less" /> <link rel="stylesheet" href="./lib/element-plus/index.css" /> <script src="./lib/vue.min.js"></script> <script src="./lib/vueDemi.js"></script> <script src="./lib/element-plus/index.full.js"></script> <script src="./lib/axios.js"></script> <script src="./lib/less.module.js"></script> </head> <body> <div id="app"> <div class="container"> <div class="initialization" v-if="showNewGame"> <div class="init-card"> <div class="init-title">新游戏</div> <div class="option"> <div class="item"> <div class="head">游戏难度</div> <div class="difficulty-list"> <button :class="{active:difficulty == '简单'}" @click="switchingDifficulty('简单')" > 简单 </button> <button :class="{active:difficulty == '普通'}" @click="switchingDifficulty('普通')" > 普通 </button> <button :class="{active:difficulty == '困难'}" @click="switchingDifficulty('困难')" > 困难 </button> </div> </div> <div class="item"> <div class="head">卡牌数量</div> <div class="card-list"> <button :class="{active:cardNum == 3}" @click="switchingCardNum(3)" > 3 V 3 </button> <button :class="{active:cardNum == 5}" @click="switchingCardNum(5)" > 5 V 5 </button> </div> </div> </div> <div class="footer"> <button @click="startTheGame" class="goGanme">开始游戏</button> </div> </div> </div> <div class="mainEventPast" v-else> <div class="left"> <el-card class="rule"> <!-- TODO 待补充代码 --> <div class="rule-item" v-for="item in ruleList"> <img src="./images/warning.png" alt="" /> <p>{{item}}</p> </div> </el-card> </div> <div class="center"> <div :style="{width:cardBoxWidth,padding:goodGuys.length == 0 ? '0' : '0 5px'}" class="top" > <div class="card"> <div class="box bad" :class="{active:i.active,flipped:i.isflipped}" v-for="(i,index) in badGuys" > <img src="./images/bgc.png" /> <div class="numerical"> <div class="head"> <img :src="i.imgUrl" alt="" /> </div> <div class="name">{{i.name}}</div> <div class="attackPower">战斗力:{{i.attackPower}}</div> <div class="defensivePower"> 防御力:{{i.defensivePower}} </div> <div class="attributeValue"> 属性值:{{i.attributeValue}} </div> </div> </div> </div> </div> <div :style="{width:cardBoxWidth,padding:goodGuys.length == 0 ? '0' : '0 5px'}" class="bottom" > <div class="card"> <div class="box flipped good" :class="{active:i.active}" v-for="(i,index) in goodGuys" > <div class="numerical" @click="playCards(i)"> <div class="head"> <img :src="i.imgUrl" alt="" /> </div> <div class="name">{{i.name}}</div> <div class="attackPower">战斗力:{{i.attackPower}}</div> <div class="defensivePower"> 防御力:{{i.defensivePower}} </div> <div class="attributeValue"> 属性值:{{i.attributeValue}} </div> </div> </div> </div> </div> </div> <div class="right"> <el-card class="newGame"> <el-button type="primary" class="newName" @click="newGame" >新游戏</el-button > <el-button type="success" class="startOver" :disabled="!newGameBtn" @click="startOver" >重新开始</el-button > </el-card> <el-card class="scoreboard"> <div class="title">记分板</div> <div class="socre"> <div class="win">胜:{{win}}</div> <div class="negative">负:{{negative}}</div> </div> </el-card> </div> </div> </div> </div> </body> <script> const { createApp, ref, computed, onMounted, watch } = Vue; const { ElNotification, ElMessageBox } = ElementPlus; const app = createApp({ setup() { const showNewGame = ref(true); const difficulty = ref("简单"); const cardNum = ref(3); const num = ref(3); const win = ref(0); const negative = ref(0); const currentCardPlayed = ref(null); const currentCardsPlayedByHumansAndMachines = ref(null); const dataList = ref([]); const goodGuys = ref([]); const badGuys = ref([]); const ruleList = ref([]); const newGameBtn = ref(true); const getDataList = async () => { //TODO 待补充代码 try { const response = await axios.get("./mock/data.json"); const data = response.data; dataList.value = data; ruleList.value = response.data[2].content .split("。") .filter((item) => item !== ""); } catch (error) { console.error("Error fetching data:", error); } }; /** * 随机获取好人卡牌 */ const getRandomGoodGuysCards = () => { //TODO 待补充代码 const goodPeople = dataList.value.find( (item) => item.name === "goodPeople" ); if (goodPeople) { goodGuys.value = goodPeople.children .sort(() => 0.5 - Math.random()) .slice(0, cardNum.value); } }; /** * 随机获取坏人卡牌 */ const getRandomBadGuysCards = () => { //TODO 待补充代码 const badPeople = dataList.value.find( (item) => item.name === "badPeople" ); if (badPeople) { badGuys.value = badPeople.children .sort(() => 0.5 - Math.random()) .slice(0, cardNum.value); } }; // 根据难度获取当前人机需要出的牌 const machinePlayCards = () => { let selectedCard = null; const attributeMap = { 火: "木", 木: "水", 水: "土", 土: "金", 金: "火", }; if (difficulty.value === "简单") { selectedCard = badGuys.value.find( (card) => attributeMap[currentCardPlayed.value.attributeValue] == card.attributeValue ); if (selectedCard) { return selectedCard; } else { return badGuys.value.sort( (a, b) => a.attackPower - b.attackPower )[0]; } } else if (difficulty.value === "普通") { return badGuys.value.sort( (a, b) => b.attackPower - a.attackPower )[0]; } else if (difficulty.value === "困难") { selectedCard = badGuys.value.find( (card) => attributeMap[card.attributeValue] == currentCardPlayed.value.attributeValue ); if (selectedCard) { return selectedCard; } else { return badGuys.value.sort( (a, b) => b.attackPower - a.attackPower )[0]; } } }; /** * 判断输赢的函数 * @param {object} goodCard * @param {object} badCard * @returns {string} result 结果 */ const judgeWinnerOrLoss = (goodCard, badCard) => { //TODO 待补充代码 let goodSum = Number(goodCard.attackPower) + Number(goodCard.defensivePower); let badSum = Number(badCard.attackPower) + Number(badCard.defensivePower); // 判断属性克制关系 if ( goodCard.attributeValue === "火" && badCard.attributeValue === "木" ) { goodSum *= 1.5; } else if ( goodCard.attributeValue === "木" && badCard.attributeValue === "水" ) { goodSum *= 1.5; } else if ( goodCard.attributeValue === "水" && badCard.attributeValue === "土" ) { goodSum *= 1.5; } else if ( goodCard.attributeValue === "土" && badCard.attributeValue === "金" ) { goodSum *= 1.5; } else if ( goodCard.attributeValue === "金" && badCard.attributeValue === "火" ) { goodSum *= 1.5; } else if ( badCard.attributeValue === "火" && goodCard.attributeValue === "木" ) { badSum *= 1.5; } else if ( badCard.attributeValue === "木" && goodCard.attributeValue === "水" ) { badSum *= 1.5; } else if ( badCard.attributeValue === "水" && goodCard.attributeValue === "土" ) { badSum *= 1.5; } else if ( badCard.attributeValue === "土" && goodCard.attributeValue === "金" ) { badSum *= 1.5; } else if ( badCard.attributeValue === "金" && goodCard.attributeValue === "火" ) { badSum *= 1.5; } return goodSum > badSum ? "win" : "loss"; }; //切换难度 const switchingDifficulty = (val) => { difficulty.value = val; }; //切换卡牌数量 const switchingCardNum = (val) => { cardNum.value = val; num.value = val; }; //开始新游戏 const startTheGame = () => { showNewGame.value = false; }; //重新开始 const startOver = () => { getDataList(); setTimeout(() => { num.value = cardNum.value; win.value = 0; negative.value = 0; goodGuys.value = []; badGuys.value = []; getRandomGoodGuysCards(); getRandomBadGuysCards(); }, 10); }; const cardBoxWidth = computed(() => { if (num.value > 0) { return 120 * num.value + 20 + "px"; } else { return 0; } }); const cardImgWidth = computed(() => { return (1 / num.value) * 100; }); const debounce = (func, delay) => { let timeout; return (...args) => { clearTimeout(timeout); timeout = setTimeout(() => { func.apply(this, args); }, delay); }; }; //出牌 const playCards = (val) => { if (currentCardPlayed.value) { return; } val.active = true; currentCardPlayed.value = val; newGameBtn.value = false; playCardsByComputer(); }; const debouncedPlayCards = debounce(playCards, 1000); //人机出牌 const playCardsByComputer = () => { const res = machinePlayCards(); res.active = true; currentCardsPlayedByHumansAndMachines.value = res; setTimeout(() => { res.isflipped = true; judge(); }, 1000); }; const judge = () => { //得到当前出牌的数据伤害 setTimeout(() => { const result = judgeWinnerOrLoss( currentCardPlayed.value, currentCardsPlayedByHumansAndMachines.value ); if (result === "win") { win.value += 1; ElNotification({ title: "Success", message: "本轮你赢了", type: "success", }); } else { negative.value += 1; ElNotification({ title: "Warning", message: "很遗憾,本轮你输了", type: "warning", }); } //清除当前出的牌 goodGuys.value = goodGuys.value.filter((item) => !item.active); badGuys.value = badGuys.value.filter((item) => !item.active); currentCardPlayed.value = null; currentCardsPlayedByHumansAndMachines.value = null; num.value -= 1; newGameBtn.value = true; }, 1500); }; onMounted(() => { getDataList(); document.body.style.backgroundColor = "rgb(79,201,249)"; }); const newGame = () => { getDataList(); setTimeout(() => { num.value = 3; cardNum.value = 3; goodGuys.value = []; badGuys.value = []; win.value = 0; negative.value = 0; difficulty.value = "简单"; showNewGame.value = true; }, 10); }; watch(showNewGame, (newValue) => { if (!newValue) { getRandomGoodGuysCards(); getRandomBadGuysCards(); document.body.style.backgroundColor = "#f5f5f5"; } else { document.body.style.backgroundColor = "rgb(79,201,249)"; } }); watch(num, (newValue) => { if (newValue == 0) { //对比胜负总数 if (win.value > negative.value) { ElMessageBox.alert("你赢了", "胜负总和", { confirmButtonText: "OK", }); } else { ElMessageBox.alert("你输了", "胜负总和", { confirmButtonText: "OK", }); } } }); return { showNewGame, cardNum, cardBoxWidth, num, cardImgWidth, dataList, goodGuys, badGuys, difficulty, ruleList, negative, currentCardPlayed, currentCardsPlayedByHumansAndMachines, win, newGameBtn, switchingDifficulty, switchingCardNum, startTheGame, playCards: debouncedPlayCards, startOver, newGame, judgeWinnerOrLoss, }; }, }); app.use(ElementPlus); let vm = app.mount("#app"); window.vm = vm; </script></html>
目标 1 检测成功 得5分目标 2 检测成功 得5分目标 3 检测失败 得0分目标 4 检测成功 得5分
第十题:消消乐
// TODO 1 START 请在下面补充代码 // 请求排行榜数据并显示消息的方法 const fetchRanking = async () => { try { const response = await axios.get(mockUrl); // 发送 GET 请求 const rankingData = response.data; // 获取响应数据 // 使用 ElMessage 显示全服最高分信息 ElMessage({ message: `全服最高分为${rankingData.top.score},由${rankingData.top.name}创造`, duration: 0, // 设置为一直显示 }); } catch (error) { console.error("请求排行榜数据时出错:", error); // 请求出错时,显示错误消息 ElMessage({ message: "无法获取排行榜数据", duration: 3000, // 显示 3 秒 }); } }; // 调用 fetchRanking 方法获取排行榜数据并显示 fetchRanking(); // TODO 1 END