第十三届蓝桥杯大赛(Web 应用开发)国赛-职业院校组题解

第十三届蓝桥杯大赛(Web 应用开发)国赛-职业院校组题解

友情链接

  • 第十四届蓝桥杯(Web 应用开发)模拟赛 3 期-大学组
  • 第十四届蓝桥杯(Web 应用开发)模拟赛 3 期-职业院校组
  • 第十四届蓝桥杯(Web 应用开发)模拟赛 2 期-大学组
  • 第十四届蓝桥杯(Web 应用开发)模拟赛 2 期-职业院校组
  • 第十三届蓝桥杯大赛(Web 应用开发)国赛-职业院校组
  • 第十三届蓝桥杯大赛(Web 应用开发)省赛-职业院校组

01 传送门 (5 分)

$(window).scroll(function ($event) {
  // 页面滚动到指定范围,对应的侧边按钮字体变色
  // TODO:请补充代码实现功能
  // 获取当前滚动条位置
  const h = document.querySelector('html').scrollTop
  // 获取导航标签
  const $children = $('#lift').children()
  if (h < 960) {
    setActive($children.eq(0))
  } else if (h >= 960 && h < 1920) {
    setActive($children.eq(2))
  } else if (h >= 1920) {
    setActive($children.eq(4))
  }
})

/**
 * 设置导航高亮
 * @param {\} $e 需要设置高亮的元素
 */
function setActive($e) {
  $e.addClass('active-color').siblings('a').removeClass('active-color')
}

/**
 * @param {Object} scrollTopVal:到达指定位置需要滚动的高度
 * 点击按钮,滚动到指定位置
 */
function toFunction(scrollTopVal) {
  // TODO:请补充代码实现功能
  document.querySelector('html').scrollTop = scrollTopVal
}

02 新鲜的蔬菜 (5 分)

/* TODO:待补充代码 */
#box1{
  display: flex;
  justify-content: center;
  align-items: center;
}

#box2{
  display: flex;
  justify-content: space-between;
}
#box2 span:last-child{
  align-self: end;
}

#box3{
  display: flex;
}
#box3 span:nth-of-type(2){
  align-self: center;
}
#box3 span:last-child{
  align-self: end;
}

03 小兔子找胡萝下(10 分)

// 定义常量 active
const active = 'active'
// 获取提示语句容器
const $result = $('.result')
// 获取输入框
const $input = $('input[type=number]')

// TODO:游戏开始
function start() {
  console.log(document.querySelector('#start'))
  document.querySelector('#start').style.display = 'none'
  document.querySelector('#move').style.display = 'block'
}

// TODO:重置游戏
function reset(e) {
  $('.container>div').eq(0).addClass(active).siblings().removeClass(active)
  $result.text('')
  $input.val('')
  $('#reset').css('display', 'none')
  $('#start').css('display', 'block')
}

// TODO:移动
function move() {
  const step = Number($input.val())
  // 如果输入的数字不正确直接 return
  if (![1, 2].includes(step)) return $result.text('输入的步数不正确,请重新输入。')
  // 获取所有草坪div
  const $div = $('.container>div')
  // 遍历草坪 div 查询当前兔子位置
  for (const div of $div) {
    // 如果当前 div 有 active 样式,则说明兔子在此位置
    if ($(div).hasClass(active)) {
      // 移除当前 div 的 active 样式
      $(div).removeClass(active)
      // 计算兔子前进坐标
      const index = $(div).index() + step
      // 给对应坐标的 div 添加 active 样式
      $div.eq(index).addClass(active)
      // 踩到炸弹提示
      if (index === 12) resetState('哎呀!兔子踩到炸弹了,游戏结束!')
      // 找到胡萝卜提示
      if (index === 23) resetState('小兔子吃到胡萝卜啦,游戏获胜!')
      break
    }
  }
}

/**
 * 隐藏移动按钮
 * 显示重置按钮
 * 根据参数输出提示
 * @param {*} tip 提示语句
 */
function resetState(tip) {
  $('#move').css('display', 'none')
  $('#reset').css('display', 'block')
  $result.text(tip)
}

04 猜硬币 (10 分)

// 将输入的值中 1-9 组成一个数组
function findNum(input_values) {
  // TODO:待补充代码
  const arr = new Set(input_values.match(/\d/g))
  return Array.from(arr).map(v => Number(v))
}

// 将 1-9 中三个不重复的随机数放入数组中,并返回这个数组
let randomCoin = () => {
  // TODO:待补充代码
  const ran = new Set()
  while (true) {
    ran.add(Math.floor(Math.random() * 9) + 1)
    if (ran.size === 3) break
  }
  return Array.from(ran)
}

05 用什么来做计算 B(15 分)

// TODO:请补充代码
const formula = document.querySelector('#formula') // 式子
const result = document.querySelector('#result') // 结果
// 给 AC 绑定事件
document.querySelector('#reset').onclick = () => {
  formula.value = ''
  result.value = ''
}
// 给 = 绑定事件
document.querySelector('#equal').onclick = () => {
  let formulaStr = formula.value
  formulaStr = formulaStr.replace('x', '*')
  formulaStr = formulaStr.replace('÷', '/')
  result.value = eval(formulaStr)
}
// 给 √ 绑定事件
document.querySelector('#sqrt').onclick = () => {
  const num = formula.value
  result.value = num < 0 ? 'NaN' : Math.pow(num, 2)
}
// 遍历按钮绑定事件
document.querySelectorAll('.calc-row div').forEach(e => {
  const keyword = e.innerText
  if (['AC', '=', '√'].includes(keyword)) return
  e.onclick = () => (formula.value += keyword)
})

06 开学礼物大放送(15 分)

07 阅读吧 (20 分)

<body>
  <div id="app">
    
    
    <a class="iconfont icon-setting" @click="show(true)">a>
    
    <transition name="fade">
      <div class="header" v-show="showHeader">
        <ul class="tools">
          <li class="container">
            <div class="left">阅读主题div>
            
            <div class="right" id="setBG">
              <a style="background-color: #f6edd4" :class="isSelected(0)" @click="changeBgColor">a>
              <a style="background-color: #ebf4ea" :class="isSelected(1)" @click="changeBgColor">a>
              <a style="background-color: #e9f2f5" :class="isSelected(2)" @click="changeBgColor">a>
              <a style="background-color: #f6e8e4" :class="isSelected(3)" @click="changeBgColor">a>
              <a style="background-color: #000000" :class="isSelected(4)" @click="changeBgColor">a>
            div>
          li>
          <li class="container">
            <div class="left">字体大小div>
            
            <div class="set-font">
              <a class="prev" @click="decrease">A-a><b>b> <span class="lang">{{fontSize}}span><b>b>
              <a class="next" @click="increase">A+a>
            div>
          li>
          <li class="container" @click="show(false)">
            
            <a class="iconfont icon-close">a>
          li>
        ul>
      div>
    transition>

    
    <p class="text-content" :style="{
          'background-color': bgColor,
          'color': color,
          'font-size': fontSize + 'px',
          'line-height': lineHeight + 'px',
    }">
      ...
      <label>————— 文章摘自著名科幻小说《三体》label>
    p>
  div>
  <script type="text/javascript" src="./js/vue.js">script>
  <script type="text/javascript">
    // TODO:请在下面实现需求
    new Vue({
      // 注意:请勿修改 data 选项中已提供的数据!!!
      el: "#app",
      data: {
        bgList: ["#f6edd4", "#ebf4ea", "#e9f2f5", "#F6E8E4", "#000000"], // 阅读主题色列表(与设置主题的圆形色块一一对应)
        showHeader: true,
        bgColor: '#f6edd4',
        fontSize: 18,
        lineHeight: 28,
        selected: 0,
      },
      computed: {
        color () {
          return this.bgColor === this.bgList[4] ? '#ffffff' : '#333333'
        },
      },
      methods: {
        show (isShow) { this.showHeader = isShow },
        isSelected (i) {
          return { 'iconfont icon-selected': i === this.selected }
        },
        changeBgColor ($e) {
          const a = document.querySelectorAll('#setBG a')
          a.forEach((e, i) => (e === $e.target) ? this.selected = i : 0)
          this.bgColor = this.bgList[this.selected]
        },
        increase () {
          if (this.fontSize === 48) return
          this.fontSize += 2
          this.lineHeight = this.fontSize + 10
        },
        decrease () {
          if (this.fontSize === 12) return
          this.fontSize -= 2
          this.lineHeight = this.fontSize + 10
        }
      }
    });
  script>
body>

html>

08 新增地址 (20 分)

/**
 * 返回当前选择的option节点以及对应下标
 * @param {*} nodes 需要遍历的option节点
 * @returns 当前节点和下标
 */
function getSelected(nodes) {
  for (const i in nodes) {
    if (nodes[i].selected) return { node: nodes[i], index: Number(i) }
  }
}

// 声明标签数组
const marks = [
  { code: 'home', name: '家' },
  { code: 'school', name: '学校' },
  { code: 'company', name: '公司' },
]
/**
 * 通过选择的标签文本获取对应的class
 * @param {*} mark 标签文本
 * @returns 返回对应的class
 */
function toMarkClass(mark) {
  for (const m of marks) {
    if (m.name === mark) {
      return m.code
    }
  }
}

// 初始化省份下拉列表内容
function provinceInit() {
  var province = document.getElementById('param_province')
  province.length = provinces.length
  for (var i = 0; i < provinces.length; i++) {
    province.options[i].text = provinces[i]
    province.options[i].value = provinces[i]
  }
}

// 选择省份后对应城市下拉列表内容渲染
function provincechange() {
  // TODO:请补充代码实现功能
  // 当前选择省份的下标
  let index = 0
  // 获取所有省份元素
  const P = document.querySelectorAll('#param_province option')
  index = getSelected(P).index
  // 获取城市容器
  const province = document.querySelector('#param_city')
  // 通过城市数量填充对应数量的option
  province.length = citys[index].length
  for (let i = 0; i < citys[index].length; i++) {
    province.options[i].text = citys[index][i]
    province.options[i].value = citys[index][i]
  }
}

/**
 * 为标签绑定单击事件。
 * 事件效果为:
 * 1、鼠标点击该标签后该标签样式显示 class=active;
 * 2、其他已选标签的 active 样式被移除;
 * 3、将选中的标签对应下标(即选择器为 “mark a” 选中的标签对应的下标)更新到 id=param_mark 的隐藏的 input 中。
 */
function addClick() {
  // TODO:请补充代码实现功能
  // 获取所有标签
  const A = document.querySelectorAll('.mark a')
  // 设置隐藏域默认值
  document.querySelector('#param_mark').value = A[0].text
  // 遍历标签并绑定点击事件
  for (const a of A) {
    a.onclick = () => {
      // 移除所有标签高亮
      A.forEach(e => e.classList.remove('active'))
      // 给当前选择的标签添加高亮
      a.classList.add('active')
      // 设置隐藏域值
      document.querySelector('#param_mark').value = a.text
    }
  }
}

/**
 * 解析表单数据
 * @returns 提交的表单数据
 */
function getFormData() {
  const address = document.querySelector('#param_address').value.trim()
  const mark = document.querySelector('#param_mark').value
  const name = document.querySelector('#param_name').value.trim()
  const phone = document.querySelector('#param_phone').value.trim()
  // 获取元素节点
  const PROVINCES = document.querySelectorAll('#param_province option')
  const CITYS = document.querySelectorAll('#param_city option')
  // 获取参数
  const province = getSelected(PROVINCES).node.text
  const city = getSelected(CITYS).node.text
  const markClass = toMarkClass(mark)
  // 拼接地址列表
  const content =
    `
      
  • ${(province, city)}
    ${address}
    ${name} ${phone}
  • `
    + document.querySelector('.address-list').innerHTML return { address, name, phone, content } } // 提交信息后,读取并显示在页面中 function saveInfo() { // TODO:请补充代码实现功能 const { address, name, phone, content } = getFormData() if (!address || !name || !phone) { document.querySelector('.warning-dialog').style.display = 'block' } else { // 渲染模板数据 document.querySelector('.address-list').innerHTML = content // 设置页面头和模块显隐 document.getElementById('main_title').innerText = '地址管理' document.querySelector('.address-list').style.display = 'block' document.querySelector('.address').style.display = 'none' document.querySelector('.user-info').style.display = 'none' } } // 切换新增地址和地址管理的显隐 function back() { if (document.getElementById('main_title').innerHTML == '地址管理') { document.getElementById('main_title').innerHTML = '新增地址' document.querySelector('.address-list').style.display = 'none' document.querySelector('.address').style.display = 'block' document.querySelector('.user-info').style.display = 'block' } } // 页面加载后的初始化操作 function init() { // 初始化省份下拉列表内容 provinceInit() // 为标签绑定单击事件 addClick() } window.onload = function () { // 初始化 init() }

    09 天气趋势 B(25分)

    <div class="month">
      <ul>
        
        <li v-for="(item,key,index) in monthList" @click="toggleMonth(key, index)" :class="active(key)">{{item}}
        li>
      ul>
    div>
    <div class="chart">
      
      
      <div id="curMonth" v-show="tipShow">
        <div class="title">
          <h3>{{typeTitle}}h3>
          <div class="type">
            <span @click="toggleTip('next')" :class="nextSeven" id="seven">未来7天span>
            <span @click="toggleTip('month')" :class="currentMonth" id="current">本月span>
          div>
        div>
      div>
      <div id="chart">div>
    div>
    
    <script>
    var vm = new Vue({
      el: "#app",
      data: {
        chart: null, // 图表
        chartOptions: null, // 图表配置项
        typeTitle: "本月天气", // tip标题
        monthList: {...},
        data: [], // 温度数据
        xDate: [], // 日期
        yDate: [], // 温度
        monthActive: 'January', // 月份高亮状态
        tipActive: 'month', // Tip高亮状态
        tipShow: false, // 本月和未来七天模块显隐
        curMonth: new Date().getMonth(), // 本月
      },
      computed: {
        currentMonth () { return this.tipActive === 'month' ? 'active' : '' },
        nextSeven () { return this.tipActive === 'next' ? 'active' : '' }
      },
      mounted: async function () {
        // 获取温度数据
        const response = await axios.get('./js/weather.json')
        this.data = response.data
        // 默认显示一月份的数据
        this.yData = this.data[0][this.monthActive]
        this.xData = this.generateMonth(this.yData.length)
        // 初始化 echarts
        this.$nextTick(() => {
          this.initChart();
        });
      },
      methods: {
        // 切换高亮
        active (key) { return this.monthActive === key ? 'active' : '' },
        // 生成x轴日期
        generateMonth (len) { return Array.from(Array(len).keys(), n => ++n) },
        // 切换月份
        toggleMonth (key, index) {
          // 设置本月tap显隐状态
          this.tipShow = index === this.curMonth
          // 替换数据
          this.yData = this.data[index][key]
          this.xData = this.generateMonth(this.yData.length)
          // 更改高亮状态
          this.monthActive = key
          this.tipActive = 'month'
          this.initChart(); // 重新加载图表
        },
        // 切换本月和未来七天
        toggleTip (key) {
          const monthKey = Object.keys(this.monthList) // 获取所有的月份key
          this.tipActive = key // 切换高亮
          if (key === 'next') {
            this.typeTitle = '未来7天天气' // 切换标题
            let { x, y } = this.analysisCurrentMonth()
            // 判断上月剩余天数是否足够7天
            if (y.length < 7) {
              const len = 7 - y.length // 缺少天数
              const { nx, ny } = this.analysisNextMonth(len, monthKey[this.curMonth + 1])
              x = [...x, ...nx]
              y = [...y, ...ny]
            }
            // x, y轴赋值
            this.yData = y
            this.xData = x
            this.initChart(); // 重新加载图表
          } else {
            this.typeTitle = '本月天气' // 切换标题
            this.toggleMonth(monthKey[this.curMonth], this.curMonth)
          }
        },
        // 解析月份
        analysis ({ data, month, start = 0, end }) {
          const x = [], y = []
          for (i = start; i < end; i++) {
            x.push(`${month}/${i + 1}`)
            y.push(data[i])
          }
          return { x, y }
        },
        // 返回当前月剩余天数
        analysisCurrentMonth () {
          const day = new Date().getDate() // 获取当天日期
          const len = this.yData.length
          const end = day + 6
          return this.analysis({
            data: this.yData,
            month: this.curMonth + 1,
            start: day - 1,
            end: end <= len ? end : len
          })
        },
        // 返回下月需要天数
        analysisNextMonth (len, key) {
          const { x, y } = this.analysis({
            data: this.data[this.curMonth + 1][key],
            end: len,
            month: this.curMonth + 2
          })
          return { nx: x, ny: y }
        },
        initChart () {...},
      },
    });
    script>
    

    10 JSON 生成器(25 分)

    /*
     * @param {*}  左侧输入框输入的值转化成的 js 数据
     * @return {*} 根据传入的数据生成对应的 js 格式数据
     */
    let generateData = data => {
      // TODO:待补充代码
      let result = null
      if (Array.isArray(data) && data.length > 1) {
        const obj = parseObj(data[1]) // 解析对象
        const range = parseNum(data[0]) // 获取repeat()中的区间值
        const len = range.length < 2 ? range[0] : random(range[0], range[1]) // 结果数组长度
        result = Array.from(Array(len), o => (o = obj)) // 生成结果数组
      } else {
        result = parseObj(data)
      }
      return result
    }
    
    /**
     * 解析传入的对象,将符合规则的值替换
     * @param {*} obj 需要处理的对象
     * @returns 解析完成的的对象
     */
    function parseObj(obj) {
      const regBool = new RegExp(/{{bool\(\)}}/)
      const regInteger = new RegExp(/{{integer\(\d+,\s?\d+\)}}/)
      for (const key in obj) {
        // 通过正则判断是否转换为 布尔值
        if (regBool.test(obj[key])) obj[key] = bool()
        // 通过正则判断是否转换为 整数值
        if (regInteger.test(obj[key])) {
          const range = parseNum(obj[key]) // 使用正则匹配数值
          obj[key] = random(range[0], range[1]) // 转换为区间随机数
        }
      }
      return obj
    }
    
    /**
     * 提取字符串中所有的数值
     * @param {*} str 需要提取的字符串
     * @returns 提取的数值数组
     */
    function parseNum(str) {
      return str.match(/\d+/g).map(e => Number(e))
    }
    
    /**
     * 随机生成 布尔值
     * @returns 生成的布尔值
     */
    function bool() {
      return random(0, 1) === 0
    }
    
    /**
     * 根据传入的值生成对应区间的随机数
     * @param {*} min 最小值(包含)
     * @param {*} max 最大值(包含)
     * @returns 对应区间的随机数
     */
    function random(min, max) {
      return Math.floor(Math.random() * (max - min + 1)) + min
    }
    
    

    你可能感兴趣的:(蓝桥杯,蓝桥杯,javascript,vue.js,html,css)