• 第十五届蓝桥杯(Web 应用开发)模拟赛 3 期-大学组(被题目描述坑惨了)


    目录

    1.创意广告牌

    2.原子化css

    3.神秘咒语

    4.朋友圈

    5.美食蛋白揭秘

    6.营业状态变更

    7.小说阅读器

    8.冰岛人

    9.这是一个”浏览器“

    10.趣味加密解密

    总结


    1.创意广告牌

    这个题目不多说了,只要知道这些css应该都能写出来,不会的平时多查查文档就记住了。

    代码:

    1. .billboard {
    2. position: relative;
    3. background-color: #8e6534;
    4. color: #fff;
    5. padding: 20px;
    6. box-shadow: 0px 5px 15px rgba(0, 0, 0, 0.3);
    7. background-size: cover;
    8. /* TODO:待补充代码 设置圆角 10px,背景图片为woodiness.jpg */
    9. border-radius: 10px;
    10. background: url('../images/woodiness.jpg');
    11. }
    12. .top-sign {
    13. position: relative;
    14. width: 200px;
    15. height: 100px;
    16. background-color: #a87f4a;
    17. display: flex;
    18. justify-content: center;
    19. align-items: center;
    20. font-size: 1rem;
    21. /* TODO:待补充代码 上面两个角是圆角 15px,下面两个角是直角 元素 x 轴倾斜 20度*/
    22. border-top-left-radius: 15px;
    23. border-top-right-radius: 15px;
    24. transform: skewX(-20deg);
    25. }

    2.原子化css

    这个题目主要需要知道的是css的属性选择器,可以查文档看看就知道了,不会的话其实看看其他的css应该也能联想到哈。

    代码:

    1. /* TODO: 实现原子化 flex */
    2. div[flex="~ col"] {
    3. display: flex;
    4. flex-direction: column;
    5. }

    3.神秘咒语

    这个考的也就是请求头携带参数,还不会的得抓紧学一下XML,fetch,axios了,这个从蓝桥杯模拟题的趋势来看,考的很频繁,甚至后面的题目发个请求就有3,5分。

    代码:

    1. const key1Button = document.getElementById('key1') // 钥匙 1
    2. const key2Button = document.getElementById('key2') // 钥匙 2
    3. const spell1 = document.getElementById('spell1') // 咒语 1
    4. const spell2 = document.getElementById('spell2') //咒语 2
    5. // TODO:新增或者修改以下代码
    6. key1Button.addEventListener('click', async () => {
    7. // 从后台请求钥匙1的咒语部分
    8. key1Button.disabled = true
    9. try {
    10. let { data } = await axios.get('/spellone', {
    11. headers: {
    12. Authorization: 'Bearer 2b58f9a8-7d73-4a9c-b8a2-9f05d6e8e3c7' // 添加 Authorization 字段携带 token
    13. }
    14. })
    15. console.log(data)
    16. spell1.innerHTML = data
    17. tryOpenTreasureBox()
    18. } catch (error) {
    19. console.error('请求钥匙1咒语失败:', error)
    20. }
    21. })
    22. key2Button.addEventListener('click', async () => {
    23. // 从后台请求钥匙2的咒语部分
    24. key2Button.disabled = true
    25. try {
    26. let { data } = await axios.get('/spelltwo', {
    27. headers: {
    28. Authorization: 'Bearer 2b58f9a8-7d73-4a9c-b8a2-9f05d6e8e3c7' // 添加 Authorization 字段携带 token
    29. }
    30. })
    31. spell2.innerHTML = data
    32. tryOpenTreasureBox()
    33. } catch (error) {
    34. console.error('请求钥匙2咒语失败:', error)
    35. }
    36. })
    37. function tryOpenTreasureBox() {
    38. if (spell1.innerHTML == '星辰闪耀' && spell2.innerHTML == '众星归位') {
    39. const box = document.getElementById('treasureBox')
    40. const suceessmessage = document.getElementById('suceess-message')
    41. box.classList.add('opened')
    42. suceessmessage.style.display = 'block'
    43. }
    44. }

    4.朋友圈

    1.防抖函数的实现

    其实这个还算挺简单的,就是一个非常常规的防抖,会的自然肯定是会的,不会的可以花几分钟时间看看视频学一下,很快的。

    代码:

    1. function debounce(fn, delay) {
    2. let timer = null
    3. return function () {
    4. const context = this
    5. const args = arguments
    6. clearTimeout(timer)
    7. timer = setTimeout(function () {
    8. fn.apply(context, args)
    9. }, delay)
    10. }
    11. }

    2.将内容存储到localStorage中

    这个按照要求做就好了,需要做哪些提示,加哪些属性都有说明。

    1. document.getElementById('text').addEventListener(
    2. 'input',
    3. debounce(function () {
    4. // 提示正在保存中
    5. document.getElementById('prompt').textContent = '正在保存中...'
    6. // 设置缓存
    7. const text = document.getElementById('text').value
    8. if (text.length <= 0) {
    9. document.getElementById('post').setAttribute('disabled', 'disabled')
    10. } else {
    11. document.getElementById('post').removeAttribute('disabled')
    12. }
    13. localStorage.setItem('savedText', text)
    14. // 过一段时间后提示保存完成
    15. setTimeout(function () {
    16. document.getElementById('prompt').textContent = '内容已保存'
    17. }, 750)
    18. }, 200)
    19. )

    3.这个就是对页面的一些动态展示了,需要理清页面渲染的流程是怎么样的,什么时候显示什么,什么情况下该显示什么,经过一些判断后添加必要的属性,类名等就行。

    1. document.getElementById('post').addEventListener('click', function () {
    2. const content = document.getElementById('text').value
    3. const element = createContent(content)
    4. document.querySelector('.contents').appendChild(element)
    5. document.getElementById('prompt').textContent = ''
    6. // TODO: 请在此补充用户点击“发表”按钮时清空文本框和缓存的代码
    7. document.getElementById('text').value = ''
    8. localStorage.removeItem('savedText')
    9. // 同时需要将按钮的 disabled 属性设置回来
    10. document.getElementById('post').setAttribute('disabled', 'disabled')
    11. })

    页面初次加载的缓存

    1. document.addEventListener('DOMContentLoaded', function () {
    2. // 页面加载时检查 localStorage 中是否有缓存文本数据
    3. const savedText = localStorage.getItem('savedText')
    4. if (savedText) {
    5. document.getElementById('text').value = savedText
    6. // 页面加载时检查输入框内容,设置按钮状态
    7. if (savedText.length > 0) {
    8. document.getElementById('post').removeAttribute('disabled')
    9. } else {
    10. document.getElementById('post').setAttribute('disabled', 'disabled')
    11. }
    12. } else {
    13. // 如果没有缓存文本数据,则将按钮设置为禁用状态
    14. document.getElementById('post').setAttribute('disabled', 'disabled')
    15. }
    16. })

    5.美食蛋白揭秘

    1.发请求拿到需要的数据

    这里的小坑就是拿到的数据渲染出来是不对的,要去除掉多余的数据

    1. async function fetchData() {
    2. // TODO:待补充代码
    3. let data = await fetch(MockURL).then(res => res.json())
    4. data.unshift({
    5. name: '表头',
    6. icon: 'none'
    7. })
    8. echartsInit(data)
    9. //去除第一个元素
    10. dataList.value = data.slice(1)
    11. }
    12. onMounted(() => {
    13. fetchData();
    14. });
    15. return {
    16. echartsInit,
    17. fetchData,
    18. dataList
    19. };

    2.渲染页面

    1. <div class="protein-item" v-for="data in dataList" :key="data.name">
    2. {{data.name}}
    3. {{data.value}}
    4. div>

    6.营业状态变更

    这个题目要实现切换状态,通过观察题目可以看到,需要返回的是一个Boolean值,这个是来确定页面该如何渲染的,第二个需要返回的是一个函数,用来切换状态的。

    首先我们要想要的是,返回的值肯定需要是一个ref(),响应式的值,因为我们知道啊,在页面不刷新的情况下,ref(),响应式数据发生变化,页面也会发生变化的,那么想到这个就好办了。

    1. function useToggle(state) {
    2. // TODO:待补充代码
    3. const toggledState = ref(state)
    4. function toggle() {
    5. toggledState.value = !toggledState.value
    6. }
    7. return [toggledState, toggle]
    8. }

    7.小说阅读器

    这个题目真的是把我坑惨了,坑的我想哭。

     但是我的解法可能有点粗糙哈,大佬看到了见谅。

    刚开始看到这个题目的数据,在解析数据过程中还好,我用的比较笨拙的办法一步步的解析出来了,提交后也能运行,json文件中的数据也有了,可是正当我提交的时候却出错了。

    这是题目描述的格式:

    这是我第一次运行出来的格式:

    感觉没有一点问题了,不过还是不行,就在我绞尽脑汁没想到办法,重新读了一遍题目,看到了这句话:

    我就修改代码将写入格式改成这种了: 空格都已经去掉了,就在我满心欢喜的提交代码时,还是出错不给过,我真的想不通到底哪里出了问题。

    最后在我看了一遍txt文件后,我再想是不是标题的问题,

    但是看题目描述的结果又是这样的,我抱着试试的感觉修改提交后,终于通过了🎉🎉🎉

    真的我要(;´༎ຶД༎ຶ`) ,太坑我了

    代码:

    1. const fs = require('fs')
    2. let readFilePath = './run/book.txt'
    3. let writeFilePath = './run/book.json'
    4. let options = 'UTF-8'
    5. //读取txt小说文件,并按对应数据格式返回。
    6. const readFile = (file) => {
    7. try {
    8. let result = null
    9. let arr = {
    10. name: '',
    11. data: []
    12. }
    13. let res = fs.readFileSync(file, { encoding: options })
    14. res = res.split('------------\n\n')
    15. for (let i = 0; i < res.length; i++) {
    16. const lines = res[i]
    17. .trim()
    18. .split('\r\n')
    19. .filter((item) => {
    20. return item !== '' && item !== '------------' && item !== ' '
    21. })
    22. arr.name = lines[0].slice(0, 8)
    23. lines.splice(0, 1)
    24. let temp1 = []
    25. let temp2 = []
    26. for (let i = 0; i < lines.length; i++) {
    27. if (lines[i].slice(0, 3) === '---') {
    28. if (temp2.length > 0) {
    29. temp2.forEach((item) => {
    30. arr.data.push(item)
    31. })
    32. }
    33. temp1.push({
    34. isRoll: true,
    35. title: lines[i]
    36. .split('---'[1])
    37. .filter((item) => item !== '')
    38. .join('')
    39. })
    40. arr.data.push(temp1[0])
    41. temp1 = []
    42. temp2 = []
    43. } else if (lines[i].slice(0, 1) === '第') {
    44. temp2.push({ title: lines[i], content: [] })
    45. } else {
    46. temp2[temp2.length - 1].content.push(lines[i].trim())
    47. }
    48. }
    49. if (temp2.length > 0) {
    50. temp2.forEach((item) => {
    51. arr.data.push(item)
    52. })
    53. }
    54. }
    55. result = arr
    56. return JSON.stringify(result)
    57. } catch (err) {
    58. return null
    59. }
    60. }
    61. //写入json文件中
    62. const writeFile = (file, data) => {
    63. try {
    64. fs.writeFileSync(file, data, { encoding: options })
    65. } catch (err) {
    66. console.log(err)
    67. }
    68. }
    69. // 执行读取文件
    70. let data = readFile(readFilePath)
    71. // console.log(data)
    72. if (data != null) writeFile(writeFilePath, data)
    73. module.exports = {
    74. writeFile,
    75. readFile
    76. }

    component组件

    1. next(value) {
    2. // TODO:待补充代码
    3. this.activeChapter += value
    4. if (this.activeChapter <= 0) {
    5. this.activeChapter = 1
    6. return
    7. }
    8. if (this.activeChapter >= this.chapters.length - 1) {
    9. this.activeChapter = this.chapters.length - 1
    10. return
    11. }
    12. //跳过卷
    13. if (this.activeChapter % 11 === 0 && value == 1) {
    14. this.activeChapter += 1
    15. }
    16. if (this.activeChapter % 11 === 0 && value == -1) {
    17. this.activeChapter -= 1
    18. }
    19. },
    20. },
    21. //通过axios发起请求json数据,并渲染界面。
    22. created() {
    23. // TODO:待补充代码
    24. axios.get('../run/book.json').then((res) => {
    25. this.bookName = res.data.name
    26. this.chapters = res.data.data
    27. })
    28. },

    8.冰岛人

    1.首先的话,我是打算先进行基本的判断,是否是不存在的人,是否是同性,然后直接输出结果

    2.找出每个人的祖先数组,然后再进行判断,查看是否满足题目要求,然后返回对应的结果。

    代码:

    1. /**
    2. * @description 通过输入的两个人的姓名返回相应的字符串
    3. * @param {array} data 当地的人口信息
    4. * @param {string} name1 要查询的两人名字之一
    5. * @param {string} name2 要查询的两人名字之一
    6. * @return {string} 根据被查询两人的名字返回对应的字符串
    7. * */
    8. function marry(data, name1, name2) {
    9. function getAncestors(person, data) {
    10. let ancestors = []
    11. //找出person的父亲或者母亲
    12. while (1) {
    13. data.forEach((item) => {
    14. if (item.givenName === /(\w+)(sson|sdottir)$/gi.exec(person.familyName)[1]) {
    15. ancestors.push(item)
    16. }
    17. })
    18. //判断是不是最后一个人了,查询ancestors的最后一个元素的familyName的后缀既不是sson也不是sdottir
    19. if (!ancestors[ancestors.length - 1].familyName.endsWith('sson') && !ancestors[ancestors.length - 1].familyName.endsWith('sdottir')) {
    20. break
    21. }
    22. //将personIndex的数据改成最新的数据
    23. person = ancestors[ancestors.length - 1]
    24. }
    25. if (ancestors.length >= 4) {
    26. ancestors.pop()
    27. }
    28. return ancestors
    29. }
    30. // 获取个人信息
    31. let person1 = data.find((person) => person.givenName === name1.split(' ')[0])
    32. let person2 = data.find((person) => person.givenName === name2.split(' ')[0])
    33. // 如果其中一个人不在名单内,则返回 NA
    34. if (!person1 || !person2) {
    35. return 'NA'
    36. }
    37. let sex1 = ''
    38. let sex2 = ''
    39. // 获取性别
    40. if (person1.familyName.endsWith('sson')) {
    41. sex1 = 'male'
    42. } else if (person1.familyName.endsWith('sdottir')) {
    43. sex1 = 'female'
    44. }
    45. if (person2.familyName.endsWith('sson')) {
    46. sex2 = 'male'
    47. } else if (person2.familyName.endsWith('sdottir')) {
    48. sex2 = 'female'
    49. }
    50. // 如果两个人为同性,则返回 Whatever
    51. if (sex1 === sex2) {
    52. return 'Whatever'
    53. }
    54. // 获取两个人的祖先数组(循环)
    55. let ancestors1 = getAncestors(person1, data)
    56. let ancestors2 = getAncestors(person2, data)
    57. console.log(ancestors1, ancestors2)
    58. // 判断是否有公共祖先
    59. let hasCommonAncestor = false
    60. for (let ancestor1 of ancestors1) {
    61. for (let ancestor2 of ancestors2) {
    62. if (ancestor1 === ancestor2) {
    63. hasCommonAncestor = true
    64. break
    65. }
    66. }
    67. }
    68. // 如果有公共祖先,则返回 No;否则返回 Yes
    69. if (hasCommonAncestor) {
    70. return 'No'
    71. } else {
    72. return 'Yes'
    73. }
    74. }
    75. module.exports = marry

    9.这是一个”浏览器“

    这个题目,第四问暂时我真没想通哪里出问题了,等解决了再更新。

    代码:

    1. 'use strict'
    2. class Tab {
    3. // 构造方法
    4. constructor(id) {
    5. // 获取元素
    6. this.main = document.querySelector(id)
    7. this.add = this.main.querySelector('.tabadd')
    8. this.ul = this.main.querySelector('.fisrstnav ul')
    9. this.fsection = this.main.querySelector('.tabscon')
    10. this.init()
    11. }
    12. // 初始化
    13. init() {
    14. this.updateNode()
    15. // init初始化操作让相关元素绑定事件
    16. this.add.onclick = this.addTab.bind(this)
    17. for (var i = 0; i < this.lis.length; i++) {
    18. this.lis[i].index = i
    19. this.lis[i].onclick = this.toggleTab.bind(this.lis[i], this)
    20. this.remove[i].onclick = this.removeTab.bind(this.remove[i], this)
    21. this.spans[i].ondblclick = this.editTab
    22. this.sections[i].ondblclick = this.editTab
    23. }
    24. }
    25. // 更新所有的li和section
    26. updateNode() {
    27. this.lis = this.main.querySelectorAll('li')
    28. this.remove = this.main.querySelectorAll('.icon-guanbi')
    29. this.sections = this.main.querySelectorAll('section')
    30. this.spans = this.main.querySelectorAll('.content')
    31. }
    32. // 1.切换功能
    33. toggleTab(tab) {
    34. // 调用 Tab 类的 clearClass 方法,清空所有标签页及其内容页的类名
    35. tab.clearClass()
    36. // 给点击的标签页和对应的内容页添加选中状态的类名
    37. this.classList.add('liactive')
    38. // 获取点击标签页的索引
    39. const activeIndex = Array.from(tab.lis).indexOf(this)
    40. // 切换内容页的选中状态类名
    41. for (let i = 0; i < tab.sections.length; i++) {
    42. if (i === activeIndex) {
    43. tab.sections[i].classList.add('conactive')
    44. } else {
    45. tab.sections[i].classList.remove('conactive')
    46. }
    47. }
    48. }
    49. // 2.清空所有标签页及其内容页类名
    50. clearClass() {
    51. for (var i = 0; i < this.lis.length; i++) {
    52. this.lis[i].className = ''
    53. this.sections[i].className = ''
    54. }
    55. }
    56. // 3.添加标签页
    57. addTab() {
    58. this.clearClass() // 清空所有标签页及其内容页的类名
    59. // 创建新的标签页和内容页
    60. const newTabIndex = this.lis.length
    61. const newTabContent = `标签页${newTabIndex + 1}`
    62. const newSectionContent = `标签页${newTabIndex + 1}的内容`
    63. // 创建新的标签页
    64. const newLi = document.createElement('li')
    65. newLi.innerHTML = `
    66. ${newTabContent}
    67. `
    68. this.ul.appendChild(newLi)
    69. // 创建新的内容页
    70. const newSection = document.createElement('section')
    71. newSection.innerText = newSectionContent
    72. this.fsection.appendChild(newSection)
    73. // 更新节点
    74. this.updateNode()
    75. // 给新标签页和内容页添加选中状态的类名
    76. this.lis[newTabIndex].classList.add('liactive')
    77. this.sections[newTabIndex].classList.add('conactive')
    78. // 重新绑定事件处理程序
    79. this.lis[newTabIndex].onclick = this.toggleTab.bind(this.lis[newTabIndex], this)
    80. this.remove[newTabIndex].onclick = this.removeTab.bind(this.remove[newTabIndex], this)
    81. }
    82. //删除节点
    83. removeTab(tab) {
    84. // 找到点击删除按钮对应的标签页及其内容页的索引
    85. const currentIndex = Array.from(tab.remove).indexOf(this)
    86. const isActive = tab.lis[currentIndex].classList.contains('liactive')
    87. // 删除标签页和内容页
    88. tab.ul.removeChild(tab.lis[currentIndex])
    89. tab.fsection.removeChild(tab.sections[currentIndex])
    90. // 更新节点
    91. tab.updateNode()
    92. // 若删除的标签页是当前选中的标签页
    93. if (isActive) {
    94. // 若删除的是最后一个标签页
    95. if (currentIndex === tab.lis.length) {
    96. // 则选中上一个标签页
    97. tab.toggleTab.call(tab.lis[currentIndex - 1], tab)
    98. } else {
    99. // 否则选中下一个标签页
    100. tab.toggleTab.call(tab.lis[currentIndex], tab)
    101. }
    102. }
    103. }
    104. // 5.修改功能
    105. editTab() {
    106. var str = this.innerHTML
    107. window.getSelection ? window.getSelection().removeAllRanges() : document.Selection.empty()
    108. this.innerHTML = ''
    109. var input = this.children[0]
    110. input.value = str
    111. input.select() //让文本框里的文字处于选定状态
    112. // 输入框失焦事件
    113. input.onblur = function () {
    114. this.parentNode.innerHTML = this.value
    115. }
    116. }
    117. }
    118. var tab = new Tab('#tab')

    10.趣味加密解密

    能力有限,真写不出来了 😭😭😭😭😭😭😭😭😭😭

    总结

    这次的模拟题是真的狠,后面的四道题难度简直是咔咔涨 不过真到比赛了,估计也没时间写后面的题目。😢

  • 相关阅读:
    统一异常ServiceException
    zookeeper/HA集群配置
    day02 MYSQL的查询操作详解
    Selenium上传文件有多少种方式?不信你有我全
    【无标题】
    网络货运平台服务模式,你真的了解吗?
    Win 7 VPN拨号错误734.
    微信表情符号写入判决书,你发的OK、炸弹都可能成为“呈堂证供”
    【BurpSuite】插件开发学习之J2EEScan - 汇总篇(主动+被动1-76)
    php 剪裁背景图,滑动图片,滑动验证
  • 原文地址:https://blog.csdn.net/m0_64642443/article/details/136659768