蓝桥杯Web应用开发

介绍

蓝桥杯在最近两期新增了一个Web应用开发赛道。如果对前端感兴趣的同学,可以尝试一下,获奖大部分学校都是有奖金的,在学习的过程中,顺便赚点生活费也是不错的。

本赛道只设立了大学组和职业院校组,比赛时间为4小时,题目为十道场景实战编程题。具体的知识点考察内容如下:

在这里插入图片描述
具体每个知识点需要掌握的内容如下:
在这里插入图片描述
具体考试情况可看官网的比赛说明:https://dasai.lanqiao.cn/notices/846/

策略

虽然看起来涉及到的知识点特别多,但是考察到的知识并不会很深入,因此对考察的每一个知识点都了解以及会做相应的题目就没有问题了。若你本身没有基础可先看官网提供的免费课程,课程会涉及到每一个要考的知识点,同时也会提供一些实操的题目。

课程

https://www.lanqiao.cn/cup/?sort=students_count&second_category_id=3
在这里插入图片描述
课程有分为大学组和职业组。课程看完之后就可以开始练题了,先做往年的真题,再做模拟题目,最后做题库中的题。若自己本身有基础,可以不用看课程直接开始做题。

题目

往年真题:https://www.lanqiao.cn/courses/9791在这里插入图片描述

模拟题目:https://www.lanqiao.cn/contests/history/
在这里插入图片描述
题库:https://www.lanqiao.cn/problems/?first_category_id=2&sort=students_count&second_category_id=11
在这里插入图片描述

题库中的题目包括了所有的真题以及模拟题,可以筛选同个类型的题目以及题目的难度。但是做真题和模拟题可以大概知道每一套题目的难度分布以及类型占比。

学习笔记

以下是我在学习过程中做的笔记,比较杂乱。可以不看,哈哈哈哈哈。
如果想看的话也可以,我的解题方式可能都比较简单粗暴,不够优雅。不过一些题目我也提供了多种解法,根据不同人习惯自己选择。其实只要找到适合自己的解决方法,能够解决相应的题目就可以啦!

1.水果拼盘

/* TODO:待补充代码 */
#pond {
  display: flex;
  flex-direction: column;
  flex-wrap: wrap;
}
/*主要考察的是弹性盒子,flex-direction用于设置方向,flex-wrap用于设置换行*/
  • flex-direction 属性,它指定了弹性子元素在父容器中的排列方向和顺序。
  • flex-wrap 属性,它指定了弹性盒子的子元素换行方式。
  • align-items 属性,它设置或检索弹性盒子元素在轴上对齐方式。
  • align-content 属性,它是用于控制多行的对齐方式

2.分一分

给你一个数组将它分割成指定长度的若干份

const splitArray = (oldArr, num) => {
  // TODO:请补充代码实现功能
  let newArr=oldArr.sort((a,b)=>a-b);
  let arr=[];
  for(var i=0;i<newArr.length;i+=num){
    arr.push(newArr.slice(i,num+i))
  }
  return arr;
};
/*主要考察数组的排序,以及slice()函数的用法*/

3.冬奥大抽奖

let rollTime; // 定义定时器变量用来清除定时器
let time = 0; // 转动次数
let speed = 300; // 转动时间间隔
let times; // 总转动次数
let num=0;

// 开始按钮点击事件后开始抽奖
$("#start").on("click", function () {
  $("#award").text(""); //清空中奖信息
  times = parseInt(Math.random() * (20 - 30 + 1) + 20, 10); // 定义总转动次数,随机20-30次
  rolling();
});
// TODO:请完善此函数
function rolling() {
  time++; // 转动次数加1
  num++;
  if(num>8){
    num=1;
  }

  $(".li"+num).addClass('active').siblings().removeClass('active');
  console.log(num)
  clearTimeout(rollTime);
  rollTime = setTimeout(() => {
    window.requestAnimationFrame(rolling); // 进行递归动画
  }, speed);

  // time > times 转动停止
  if (time > times) {
    $("#award").text(`恭喜你抽到了${$('.li'+num).text()}`)
    clearInterval(rollTime);
    time = 0;
    num=0;
    return;
  }
}
//主要涉及到的知识点时类的添加移除以及对兄弟元素的操作。text的使用,以及jquery对元素的获取方式。
//如果使用jquery对元素添加类,则是addClass(),移除则是removeClass()。使用JS进行添加则是classList.add(),移除则是classList.remove()

补充:

选择器:

Jquery中的后代选择器:我们使用 $("#father p") 来选择 id 名为 father 的 div 元素中的所有后代 p 元素。

子代选择器:我们使用 "#father>p" 只选择出 "id="father" 的子代 p 元素,即儿子节点,这就是它和后代选择器的区别

兄弟选择器:$(“M~N”);

相邻选择器:$(“M+N”); // 选择下一个兄弟节点 N

属性选择器:

选择器说明
E[attr]对带有 attr 属性的 E 元素进行操作。
E[attr="value"]对 attr 值等于 value 的 E 元素进行操作。
E[attr !="value"]对 attr 值不等于 value 的 E 元素进行操作。
E[attr ^="value"]对带有 attr 属性,其属性值以 value 字符串开头的 E 元素进行操作。
E[attr $="value"]对带有 attr 属性,其属性值以 value 字符串结尾的 E 元素进行操作。
E[attr *="value"]对带有 attr 属性,其属性值包含 value 字符串的 E 元素进行操作。
E[attr ~="value"]对带有 attr 属性,其属性值为 value 或者包含 value 的 E 元素进行操作。
`E[attr=“value”]`

伪类选择器:

选择器说明
:first选取指定元素的第一个该元素。
:last选取指定元素的最后一个该元素。
:odd选取指定元素序号为奇数的所有该元素。
:even选取指定元素序号为偶数的所有该元素。
:eq(n)选取指定元素的第 n 个该元素。
:lt(n)选择指定元素中小于 n 的所有该元素。
:gt(n)选取指定元素中大于 n 的所有该元素。

绑定事件:jQuery对象.on(事件类型, 事件处理函数);

jQuery对象.bind(事件类型, 事件处理函数);

创建元素节点:

$(“<标签名>文本内容</标签名>”);

$(“<标签名 属性=‘属性值’>文本内容</标签名>”);

 var div = $(
            "<div style='width:50px; height:50px; background-color: #ddffbc'>嗨</div>"
          ); // 创建带有属性的元素节点
          $("body").append(div); // 将创建的 div 元素放入 body 中

元素的插入:
prepend()prependTo() 是在元素子级开头插入元素。

// 在 A 元素的子级最前面的位置插入B
$(A).prepend(B);

// 在 A 元素的子级最前面的位置插入B
$(B).prependTo(A);

append()appendTo() 是在元素子级尾部插入元素。

before()insertBefore() 是在该元素的前面插入元素。

after()insertAfter() 是在元素的后面插入元素。

empty 方法是用来清空指定元素的后代元素和内容的。

replaceWith 方法和 replaceAll 方法都可以用来把指定元素替换成其他元素,只是在使用格式上有些差别。

// 将 A 替换为 B
$(A).replaceWith(B);

// 将 A 替换为 B
$(B).replaceAll(A);

元素的遍历:

$().each(function (index, element) {});

each 方法会接收一个匿名函数作为参数,函数中的 index 表示元素的索引号;而函数中的 element 表示当前元素。

attr 方法可以用来获取指定元素的属性值,也可以用来设置指定属性的属性值。

jQuery对象.attr("属性名"); // 获取属性
jQuery对象.attr("属性名", "属性值"); // 修改属性

removeAttr 方法可以删除指定元素的某个属性。

toggleClass 方法是用来切换类选择器的。通过使用 toggleClassdiv 元素的 circle1 样式在添加和移除之间切换,没有 circle1 这个类就加上,有则移除。

val 方法用于获取表单元素的值,也可以给表单元素设置值。

$().prev(); // 查找指定元素前向第一个元素
$().preAll(); // 查找指定元素前向所有元素
$().next(); // 查找指定元素的第一个后向兄弟元素
$().nextAll(); // 查找指定元素的所有后向兄弟元素
$().siblings();//查找所有兄弟元素
jQuery对象.children();//获取元素的儿子节点
jQuery对象.find(selector);//查找到指定元素的所有后代元素
$().hasClass("类名");//用来判断指定元素是否包含该类名的元素
$().eq(n);//使用 eq 方法可以实现下标过滤
$().is(selector);//使用 is 方法来判断指定元素中是否有符合条件的存在
$().not(selector|function)//用 not 方法可以选择不符合条件的元素。

4.灯的颜色变化

// TODO:完善此函数 显示红色颜色的灯
function red() {
    setTimeout(()=>{
        document.getElementById("redlight").style.display="inline-block";
        document.getElementById("defaultlight").style.display="none";
    },3000)
}

// TODO:完善此函数  显示绿色颜色的灯
function green() {
    setTimeout(()=>{
        document.getElementById("redlight").style.display="none";
        document.getElementById("greenlight").style.display="inline-block";
    },6000)
}

// TODO:完善此函数
function trafficlights() {
    red()
    green()
}
trafficlights();

使用Promise进行分装,实现异步编程

// TODO:完善此函数 显示红色颜色的灯
function red() {
    return new Promise ((resovle,reject)=>{
        setTimeout(()=>{
            document.getElementById("redlight").style.display="inline-block";
            document.getElementById("defaultlight").style.display="none";
            resovle()
        },3000)
    })
}

// TODO:完善此函数  显示绿色颜色的灯
function green() {
    return new Promise((resovle,reject)=>{
        setTimeout(()=>{
            document.getElementById("redlight").style.display="none";
            document.getElementById("greenlight").style.display="inline-block";
        },3000)
        resovle()
    })
}

// TODO:完善此函数
async function trafficlights() {
   await red()
   await green()
}

trafficlights();

补充ES6相关知识点:

使用 Object.is 来比较两个值是否相等。console.log(Object.is(-0, +0)); // false

Object.assign 来合并对象,该方法一个对象可以接受任意多个对象的属性和方法。被合并的对象中出现同名属性,后面的对象会覆盖前面的对象中的属性值。

Set 是 ES6 提供的一种新的数据结构,其结构与数组类似,但与数组不同的是 Set 里面不允许存放相同的元素,也就是说 Set 中的每个值都是独一无二的。可以使用如下的方式对一个有重复元素的数组进行去重:

 <script>
        var arr=[1,2,3,2,3,4,5,3,5]
        let arr2=new Set();
        arr.forEach(element => {
            arr2.add(element) 
        });
        console.log(arr2)
    </script>

includes():判断是否包含指定字符串,如果包含返回 true,反之 false。

startsWith():判断当前字符串是否以指定的子字符串开头,如果是则返回 true,反之 false。

endsWith():判断当前字符串是否以指定的子字符串结尾,如果是则返回 true,反之 false。

repeat(n) 方法用于返回一个重复 n 次原字符串的新字符串,其参数 n 为整数,如果设置 n 为小数,会自动转换为整数。

replaceAll() 方法来解决这个问题,它可以用来替换所有匹配的字符串。string.replaceAll(“待替换的字符”, “替换后的新字符”);

Array.from() 方法可以将以下两类对象转为数组。

  • 类似数组的对象(array-like-object)。
  • 可遍历的对象(iterable-object)。

find() 方法是用于从数组中寻找一个符合指定条件的值,该方法返回的是第一个符合条件的元素,如果没找到,则返回 undefined.

findIndex() 方法返回数组中第一个符合指定条件的元素的索引下标值,如果整个数组没有符合条件的元素,则返回 -1。

fill() 方法是用指定的值来填充原始数组的元素。array.fill(value, start, end);

entries()keys()values() 是 ES6 中三种数组的遍历方法,三个方法返回的都是 Array Iterator 对象.我们要输出 Array Iterator 对象里的值,可以用前面提到过的扩展运算符(…)来展开。

for...of 就摆脱了计数器、退出条件等烦恼,它是通过迭代对象的值来循环的。它能迭代的数据结构很多,数组、字符串、列表等。但在本实验中我们重点放在数组的遍历上。for(let name of arr)

扩展运算符(…)是 ES6 的新语法,它可以将可迭代对象的参数在语法层面上进行展开。数组对象都可用。

let animals = ["兔子🐰", "猫咪🐱"];
let zoo = [...animals, "老虎🐯", "乌龟🐢", "鱼🐟"];
console.log(zoo);

5.购物车

<script>
    new Vue({
        el: '#app',
        data: {
          cartList:[],
          goodsList:[]
        },
        mounted() {
          this.goodsList = GoodsArr;
        },
        methods:{
            addToCart(goods){
                // TODO:修改当前函数,实现购物车加入商品需求
                const flag=false;
                this.cartList.forEach(element => {
                  if(element.id==goods.id){
                    goods.num++;
                    flag=true;
                  }
                });
                if(!flag){
                    goods.num = 1;
                    this.cartList.push(goods);
                  }
                this.cartList = JSON.parse(JSON.stringify(this.cartList));
            },
            removeGoods(goods){
                // TODO:补全代码实现需求
                this.cartList.forEach((element,index) => {
                  if(element.id==goods.id){
                    goods.num--;
                    if(goods.num<=0){
                      this.cartList.splice(index,1)
                    }
                  }
                });
            }
        }
    });
</script>

6.类型判断

请封装一个函数,能够以字符串的形式精准地返回数据类型。要求返回的类型全部由小写字母组成。

输入输出
true‘boolean’
100‘number’
‘abc’‘string’
100n‘bigint’
null‘null’
undefined‘undefined’
Symbol(‘a’)‘symbol’
[]‘array’
{}‘object’
function fn() {}‘function’
new Date()‘date’
/abc/‘regexp’
new Error()‘error’
new Map()‘map’
new Set()‘set’
new WeakMap()‘weakmap’
new WeakSet()‘weakset’
function getType (target) {
  var type=typeof target;
  if(type!=="object"){
    return type;
  }
  return Object.prototype.toString.call(target).slice(8,-1).toLocaleLowerCase()//-1表示倒数第一位不包括倒数第一位
}

7.商品销量和销售额实时展示看板

async function renderChart() {
    const result = await Ajax();
    document.querySelector("#result").innerText = JSON.stringify(result);
    const myChart = echarts.init(document.getElementById('main'));
    // TODO:补全代码,正确给 X 轴的时间,以及 Y 轴的商品的销售额 saleObj 和销量赋值 countObj。
    console.log(result)
    charData.xAxis.data = Object.keys(result.data.countObj);
    //Object.keys()方法会返回一个由一个给定对象的自身可枚举属性组成的数组,数组中属性名的排序和使用for..in循环遍历对象时返回的顺序一致。
    //传入数组,和字符串都返回索引值。构造函数,返回空数组或者属性名。
    charData.series[0].data = Object.values(result.data.saleObj);
    charData.series[1].data = Object.values(result.data.countObj);
    myChart.setOption(charData, true);
    document.querySelector("#data").innerText = JSON.stringify(charData);
}
//result.data?.saleObj是ECMScript2020引入的一种可选链语法,它允许访问对象的属性,而不会在对象为nullish(null或underfined)时引发错误。如果对象为nullish,则表达式将计算为underfined。
async function renderChart() {
    const result = await Ajax();
    document.querySelector("#result").innerText = JSON.stringify(result);
    const myChart = echarts.init(document.getElementById('main'));
    // TODO:补全代码,正确给 X 轴的时间,以及 Y 轴的商品的销售额 saleObj 和销量赋值 countObj。
    console.log(result)
    if(result.data?.saleObj){
        charData.xAxis.data=Object.keys(result.data.saleObj);
        charData.series[0].data = Object.values(result.data.saleObj);
    }
    if(result.data?.countObj){
        charData.series[1].data = Object.values(result.data.countObj);
    }
    myChart.setOption(charData, true);
    document.querySelector("#data").innerText = JSON.stringify(charData);
}

8.粒粒皆辛苦

主要是考察数据的请求,以及通过获取到的数据修改原本的数据,将数据正确的展现出来。实现的方式有种。


      // TODO: 待补充代码
      // axios.get('./data.json').then(res=>{
      //   let data = res.data.data;
      //   let source=[
      //         ["全部", "2017", "2018", "2019", "2020", "2021", "2022"],
      //         ["小麦"],
      //         ["大豆"],
      //         ["马铃薯"],
      //         ["玉米"],
      //       ]
      //   for(let item in data){
      //     source[1].push(data[item].wheat);
      //     source[2].push(data[item].soybean);
      //     source[3].push(data[item].potato);
      //     source[4].push(data[item].corn);
      //   }
      //   option.dataset.source= source;
      //   myChart.setOption(option);
      // })
      
      let chineseNameMap=new Map([
        ["wheat","小麦"],
        ['soybean',"大豆"],
        ["potato","马铃薯"],
        ["corn","玉米"]
      ]);
      let convertData=(data)=>{
        let res=[];
        let years=Object.keys(data);
        years=['全部',...years];
        res.push(years);
        let obj={};
        Object.values(data).map((item)=>{
          for(let k in item){
            if(k in obj){
              obj[k].push(item[k])
            }
            else{
              obj[k]=[chineseNameMap.get(k),item[k]]
            }
          }
        });
        console.log(obj);
        res.push(...Object.values(obj));
        console.log(res);
        return res;
      };
      axios.get("./data.json").then((res)=>{
        option.dataset.source=convertData(res.data.data);//需要在数据请求里面
        myChart.setOption(option);
      });

demo1.html 中使用 Axios 发送一个简单的 Ajax 请求,用于获取 test.json 中的数据,并输出在控制台:

<script type="text/javascript">
  axios.get("./test.json").then((res) => {
    console.log(res);
  });
//通过 Axios 获取到的数据实际上就是一个 Ajax 对象,真正需要我们请求的数据是该 Ajax 对象的 `data` 属性值。
//因此可以通过res.data来获取其中的数据对象,再根据具体的名字来获取对应的具体数值

执行get数据请求:

axios.get('url',{
  params:{
    id:'接口配置参数(相当于url?id=xxxx)'},
}).then(function(res){
  console.log(res); // 处理成功的函数 相当于 success
}).catch(function(error){
  console.log(error) // 错误处理 相当于 error
})

执行post数据请求并发送数据给后端

axios
  .post(
    "url",
    { data: {} },
    {
      headers: "xxxx", // 头部配置
    }
  )
  .then(function (res) {
    console.log(res); // 处理成功的函数 相当于 success
  })
  .catch(function (error) {
    console.log(error); // 错误处理 相当于 error
  });

通用方式

//-------------------get-----------------------//
axios({
  method: "get",
  url: "xxx",
  cache: false,
  params: {
    id: 123,
  },
  headers: "xxx",
});
//-------------------post-----------------------//
axios({
  method: "post",
  url: "xxx",
  data: {
    firstName: "Tom",
    lastName: "Sun",
  },
});

9.水果叠叠乐

(存在的问题:对于如何将放入盒子中连续相同的图片删除的步骤没有思路。功能理解错误,导致实现起来更加地困难。只需要实现当在容器中出现了累积三个相等的图片时,才需要进行删除。但是依旧没有思路。主要困难之一是获取不到对应子元素的data-id的属性。不知如何对并且的四类图片进行统计。)

  $("#card li").on("click", function (e) {
        // TODO: 待补充代码
        if(document.querySelectorAll('#box li').length < 7){
          // 克隆节点
          const cloneNode = this.cloneNode(true)
          // 下方添加
          document.querySelector('#box').appendChild(cloneNode)
          // 上方隐藏
          this.style.display='none'
          // 遍历
          for(let i = 1;i<=4;i++){
            // 通过属性选择器获取下方卡槽所有自定义属性id相同的节点
            const lis = document.querySelectorAll(`#box li[data-id="${i}"]`)
            // console.log(lis)
            // 相同节点个数等于3时全部删除
            if(lis.length===3){
              lis.forEach(item=>{
                item.remove()
              })
            }
          }
        }
      });

方式二:
  $("#card li").on("click", function (e) {
        // TODO: 待补充代码
        let copy = $(this).clone();//克隆点击的元素。$(this)则是所点击的元素,通过clone()方法来进行克隆。
        if($('#box').children().length<7){
          $('#box').append(copy)
          $(this).hide()
        }
        let flag = 0;
        let data = $(this).attr("data-id");//若想要获取到元素的某个属性,应该采用attr()方法来获取
        $("#box li").each(function (i,e) {
          if($(this).attr("data-id")==data){
            flag++;
          }
        })
        if (flag==3) {
          $("#box li").each(function (i,e){
            if($(this).attr("data-id")==data){
              $(this).remove()
            }
          })
          flag = 0;
        }
      });

问题:1.在一段js代码中是否js以及$可以混用。

可以混合使用,不过需要注意各自相同的方法可能表示方式并不一样。

2.添加元素以及删除元素对应的方式:append()以及appendChild()有什么区别。

都是用于向DOM树中添加新的节点,append()方法是jquery库提供的,而appendChild()是DOM原生的。

3.each()遍历方式与forEach()方式有什么区别,分别运用在哪些情况。

each()是jquery库提供的方法,而forEach()是js原生提供的。都用于遍历数组或者类数组。each()方法没有返回值而forEach()返回underfined。

4.哪些方法是jquery独有的

获取父元素中的子元素用到的方法是:children()而在js中则是children,没有括号。

jQuery 提供了大量的方法,以下是一些常用的方法:

  1. 选择器方法:$()find()filter()not()eq()first()last()parent()parents() 等。兄弟选择器: ( " M   N " ) 。相邻选择器: ("M~N")。相邻选择器: ("M N")。相邻选择器:(“M+N”)

  2. DOM 操作方法:html()text()val()append()prepend()after()before()remove()empty() 等。

  3. 样式操作方法:addClass()removeClass()toggleClass()attr()prop()css()height()width() 等。

  4. 事件处理方法:on()off()click()hover()focus()blur()submit()keydown() 等。

    在 jQuery 中,我们使用 on 或 bind 方法可以绑定一个或者多个事件。jQuery对象.on(事件类型, 事件处理函数); jQuery对象.bind(事件类型, 事件处理函数);

  5. AJAX 相关方法:$.ajax()$.get()$.post()$.getJSON()$.load()$.ajaxSetup() 等。

  6. 动画效果方法:show()hide()fadeIn()fadeOut()slideUp()slideDown()animate() 等。

  7. 工具方法:$.trim()$.isArray()$.each()$.extend()$.proxy()$.noop() 等。

  8. 事件说明
    click单击左键事件。
    mouseover鼠标移入事件。
    mouseout鼠标移出事件。
    mousedown鼠标按下事件。
    mouseup鼠标松开事件。
    mousemove鼠标移动事件。

6.js中的方法:

arr.slice(2, 4); 表示取名为 arr 的数组中下标从 2 到 4 的值。

数组名.unshift(待添加项); unshift() 可以在数组的头部增加新的元素。

数组名.shift(); shift() 可以删除数组的首元素。

数组名.sort(); sort() 可以给数组中的元素从小到大进行排序。

数组名.reverse(); reverse() 可以将数组中的元素进行逆序排列。

数值名.join(); join() 可以将数组中的字符拼接成字符串。

数组1.concat(数组2); concat() 可以将两个数组拼接在一起。

数组.includes(元素); includes() 可以用来判断该数组中是否包含某个元素。

数组名.toString(); toString() 可以将数组中的值转换成字符串类型。

arr.indexOf(元素); indexOf() 可以用来查找指定元素的下标值。

字符串.toLowerCase(); toLowerCase() 可以把字符串的大写字母转换成小写字母。

字符串.toUpperCase(); toUpperCase() 可以把字符串中的小写字母转换成大写字母。

字符串.charAt(下标值); charAt() 是用于根据指定下标从一个字符串中返回指定的字符。

字符串.substring(); substring() 可以通过下标来选取字符串中的部分字符。

字符串.replace(待替换的字符串, 新的字符串); replace() 可以用来替换指定字符串的内容。

字符串.split(); split 可以使用指定的分隔符将一个字符串分割成子字符串数组。

字符串.indexOf(字符); indexOf() 是寻找某个字符在字符串中首次出现的位置

prompt()显示可提示用户输入的对话框

  • 鼠标事件:
    • onclick
    • onmouseover
    • onmouseout
    • onmousedown
    • onmouseup
    • onmousemove
  • 键盘事件:
    • onkeydown
    • onkeyup
  • 表单事件:
    • onfocus
    • onblur
document.querySelector()通过选择器获取第一个元素。
document.querySelectorAll()通过选择器获取所有元素。
document.createElement()创建元素节点。
document.createTextNode()创建文本节点。
document.write()输出内容。
document.writeln()输出内容并换行。

10.展开你的扇子

#box:hover #item1{
  rotate: -60deg;

}
#box:hover #item2{
  rotate: -50deg;

}
#box:hover #item3{
  rotate: -40deg;

}
#box:hover #item4{
  rotate: -30deg;

}
#box:hover #item5{
  rotate: -20deg;

}
#box:hover #item6{
  rotate: -10deg;

}
#box:hover #item7{
  rotate: 10deg;

}
#box:hover #item8{
  rotate: 20deg;

}
#box:hover #item9{
  rotate: 30deg;

}
#box:hover #item10{
  rotate: 40deg;

}
#box:hover #item11{
  rotate: 50deg;

}
#box:hover #item12{
  rotate: 60deg;

}

11.宝贵的一票

(存在多次增加删除键的问题,删除之后解决不了选项名称顺序排列的问题)

问题1解决方式:在进行加入删除图标之前需要先进行判断,判断每一个class="mb-3 row item"的div 中是否存在子元素,class="col-sm-1"的div 。若存在则添加,否则不添加。存在的问题:元素添加之前元素的创建方式,如何判断该元素中是否存在某个元素。

问题2解决方式:仍然使用遍历的方式,对class="mb-3 row item"的div中的子元素进行遍历。在子元素中直接使用find()方法来找到我们想要的第一个元素,然后使用html()方法来对其内容进行修改。

     $(".add").click(function () {
            // TODO 待补充代码
            let num=$(".list input").length
            let initList = initRender(`选项${num+1}`);
            $(".list").append(initList);
          
            // console.log($(".list div div"))
            if(num+1>2){
              $(".list").children().each((i,item)=>{
                // console.log($(item).html())
                const flag=$(item).html().includes('<div class="col-sm-1">')//判断该元素中是否存在某个元素。细节:一定要是双引号在里面里面,不然一直都是判断错误。
                var doc=$("<div class='col-sm-1'><img class='del-icon' src='./images/x.svg' alt='' /></div>")//节点的创建应该在遍历里面,不然的话一直无法渲染第一和二两个选项。
                if(!flag){
                  $(item).append(doc);
                }
              })
            }

          });
          // 点击 x 删除逻辑,列表小于 2 项时不显示删除图标
          $(document).on("click", ".del-icon", function () {
            // TODO 待补充代码
            let num=$(".list input").length
            $(this).parent().parent().remove()
            // console.log(num-1)
            $(".list").children().each((i,item)=>{
              const label=$(item).find("label")//find()方法为返回被选元素的后代元素。find(*)可以返回所有的后代元素。
             // const label=$(item).children(":first-child") 也可以选址第一个子元素。使用children()方法
              label.html(`选项${i+1}`)
            })
            if(num-1<=2){
              $(".col-sm-1").remove();
            }
          });
        })()
      );

12.渐变色背景生成器

存在问题:对于change事件不熟悉,不知如何将修改的值传给css变量。

问题1解决方式:事件监听,有两种设置方法,其一为设置他们的onxxx属性,比如:obj.οnclick=function(){}。 使用addEventListener()方法。obj.addEventListener(‘click’,function(){},ture) true表示监听捕获阶段,false表示监听冒泡阶段。可以不写。obj.addEventListener(‘click’,function(){},ture) 相等于obj.addEventListenter(“click”,()=>{},true)。

问题2解决方法:setProperty()方法可以对css变量进行值的修改。

方法1const inputs = document.querySelectorAll(".controls input");
let gra = document.querySelector(".gradient")
inputs[0].addEventListener("change",()=>{
    gra.style.setProperty("--color1", inputs[0].value);
})
inputs[1].addEventListener("change",()=>{
    gra.style.setProperty("--color2", inputs[1].value);
})

方法2// inputs.forEach((item,index)=>{
//     item.addEventListener("change",()=>{
//         gra.style.setProperty("--color"+(index+1), item.value);
//     })
// });

13.http 模块应用

//通过在 app.js 书写代码,创建一个服务器,使服务在 8080 端口运行。
//通过 node app.js 运行代码,使服务处于运行状态,点击右侧 【web 服务】,页面上显示 “hello world” 。
const http=require("http");
const app=http.createServer();
app.on('request',(req,res)=>{
    res.end("hello");
});
app.listen(8080)
解法2const http=require("http");
const app=http.createServer((req,res)=>{
	res.end("hello world")
});
app.listen(8080)
const http = require("http");

const server = http.createServer((req, res) => {
  if (req.method === "POST") {
    console.log("content-type:", req.headers["content-type"]); // 获取请求类型 application/json

    //读post数据
    let postData = ""; // postData 用来存储传递给服务器的全部数据
    // 分段循环传输数据,每次传递数据都会执行后面的回调函数
    req.on("data", (chunk) => {
      postData += chunk.toString(); // chunk是二进制数据 所以要把它转换成字符串
    });

    // 当数据传输完毕会执行 end 事件后的回调函数
    req.on("end", () => {
      console.log("postData:", postData);
      res.end("Hello"); //在这里返回因为是异步
    });
    console.log("test"); //这里先被打印 因为上面的代码是异步的
  }
});

server.listen(8080, () => {
  console.log("服务器运行在 8080 端口...");
});

14.资讯接口

  1. 通过在 app.js 书写代码,创建一个服务器,使服务在 8080 端口运行。
  2. 访问 /news 返回资讯数据,访问其他任意路径均返回字符串 404
// TODO: 待补充代码
const http=require("http")
data = [{
    "channelId": "5572a108b3cdc86cf39001cd",
    "name": "国内焦点"
},
{
    "channelId": "5572a108b3cdc86cf39001ce",
    "name": "国际焦点"
}
]
const app=http.createServer((req,res)=>{
    res.setHeader("Content-type", "text/html;charset=utf8");
    if (req.url === '/news') {
        // 将数据转化成json文件形式
        res.end(JSON.stringify(data))
    }else {
        res.end('404 NOT FOUND');
    }
})
app.listen(8080)

补充:JSON对象包含两个方法:parse()方法以及stringify()方法。第一个方法有两个参数,第一个参数传入一个符合JSON格式的字符串,会转化为对象返回。 stringify()有三个参数,传入一个对象转换为JSON格式的字符串。

15.封装Promisefy函数

请在 index.js 文件中的补全代码,完成 promisefy 函数的封装。将 fs 中的 readFile 方法 promise 化。也就是说 readFileSync 方法执行后,会返回一个 promise,可以调用 then 方法执行成功的回调或失败的回调。

在实际应用中,一个函数满足这几个条件,就可以被 promisify 化:

  • 该方法必须包含回调函数
  • 回调函数必须执行
  • 回到函数第一个参数代表 err 信息,第二个参数代表成功返回的结果
const promisefy = (fn) => {
  // TODO 此处完成该函数的封装
  return function(...args){
    return new Promise((resolve,reject)=>{
      fn(...args,(err,result)=>{
        if(err){
          reject(err);
        }else{
          resolve(result)
        }
      })
    })
  }
}

在这里插入图片描述

16.蓝桥知识网

在这里插入图片描述

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"
    />
    <title>蓝桥知识网</title>
    <link rel="stylesheet" href="./css/style.css" />
  </head>
  <body>
    <!--TODO:请补充代码-->
    <div class="header">
        <div class="sn1"></div>
          <ul class="sun1">
            <li class="left">蓝桥知识网</li>
            <li class="right" id="right">首页</li>
            <li class="right">热门技术</li>
            <li class="right">使用手册</li>
            <li class="right">知识库</li>
            <li class="right">练习题</li>
            <li class="right">联系我们</li>
            <li class="right">更多</li>
          </ul>
        <div id="box">
          <div class="sn2"></div>
          <p class="sun2">蓝桥云课</p>
          <div class="sn3"></div>
          <div class="sun3">随时随地丰富你的技术栈!</div>
          <div class="sn4"></div>
          <div class="sun4">加入我们</div>
        </div>
        
    </div>
    <div class="middle">
      <div class="md1"></div>
      <div class="md2">
        <div class="mi" id="mi3">
          <p>人工智能</p>
          <div class="p">人工智能亦称智械、机器智能,指由人制造出来的机器所表现出来的智能。通常人工智能是指通过普通计算机程序来呈现人类智能的技术。
            前端开发</div>
        </div>
        <div class="mi" id="mi1">
          <p>前端开发</p>
          <div class="p">前端开发是创建 WEB 页面或 APP 等前端界面呈现给用户的过程,通过 HTML,CSS 及 JavaScript 以及衍生出来的各种技术、框架、解决方案,来实现互联网产品的用户界面交互。</div>
        </div>
        <div class="mi">
          <p>后端开发</p>
          <div class="p">后端开发是实现页面的交互逻辑,通过使用后端语言来实现页面的操作功能,例如登录、注册等。</div>
        </div>
        <div class="mi" id="mi2">
          <p>信息安全</p>
          <div class="p">ISO(国际标准化组织)的定义为:为数据处理系统建立和采用的技术、管理上的安全保护,为的是保护计算机硬件、软件、数据不因偶然和恶意的原因而遭到破坏、更改和泄露。</div>
        </div>
      </div>
    </div>
    <div class="footer">
      <div class="fo">
        <!-- <div class="fo1"></div> -->
        <div class="fo2">© 蓝桥云课 2022</div>
        <!-- <div class="fo3"></div> -->
        <div class="fo4">京公网安备 11010102005690 号 | 京 ICP 备 2021029920 号</div>
      </div>
    </div>
    
  </body>
</html>

/*
 TODO:请补充代码
*/
.header{
    width: 100%;
    height: 486px;
    background-color: #a6b1e1;
    position: relative;
}
.sn1{
    width: 1024px;
    height: 13px;
    /* background-color: blanchedalmond; */
    margin: 0 auto;
}
.sun1{
    width: 1024px;
    height: 46px;
    /* background-color: blanchedalmond; */
    margin: 0 auto;
    list-style: none;
    padding: 10px;

}
.sun1 .left,.sun1 .right{
    color: white;
}
.sun1 .left{
    font-size: 18px;
    float: left;
    line-height: 46px;
    margin-right: 365px;
}

.sun1 .right{
    font-size: 16px;
    float: left;
    /* margin-left: 16px; */
    line-height: 46px;
    margin:0 15px;
}
#right{
    /* margin-left: 365px; */
}
#box{
    width: 1024px;
    height:427px;
    /* background-color: beige; */
    margin: 0 auto;
    text-align: center;
}
.sn2{
    width: 1024px;
    height: 30px;
    /* background-color: blanchedalmond; */
    margin: 0 auto;
}
.sun2{
    color: black;
    font-size: 45px;
    margin: 0 auto;
    /* width: 100px; */


}
.sn3{
    width: 1024px;
    height: 62px;
    /* background-color: blanchedalmond; */
    margin: 0 auto;
}
.sun3{
    color: white;
    font-size: 21px;
    margin: 0 auto;

}
.sn4{
    width: 1024px;
    height: 36px;
    /* background-color: blanchedalmond; */
    margin: 0 auto;
}
.sun4{
    width: 100px;
    height: 50px;
    color: #efbfbf;
    font-size: 18px;
    border: 1px solid #efbfbf;
    border-radius: 2px;
    box-shadow: inset 0 0 0 2px #efbfbf;
    line-height: 50px;
    margin: 0 auto;
}
.middle{
    width: 100%;
    height: 376px;
}
.md1{
    width: 1024px;
    height: 74px;
    margin: 0 auto;
}
.md2{
    width:1024px;
    height: 302px;
    margin: 0 auto;
    /* background-color: antiquewhite; */
}
.md2 .mi{
    width: 502px;
    height: 144px;
    /* background-color: blue; */
    float: left;
}
#mi3,#mi1{
    margin-bottom: 20px;
}
#mi1,#mi2{
    margin-left:20px;
}
.md2 p{
    font-size: 30px;
    color: black;
    font-weight: 200;
    margin-top: 0;
    margin-bottom: 10px;
}
.p{
    font-size: 18px;
    color: #aaa;
    line-height: 1.4em;
}
.footer{
    width:100%;
    height:80px;
    border-top: 3px solid rgb(196, 194, 194);
}
.fo{
    padding-top: 30px;
    text-align: center;
    width: 1024px;
    height: 80px;
    /* background-color: bisque; */
    margin: 0 auto;
    color: #aaa;
    font-size: 14px;
}
.fo4{
    margin-top: 10px;
}

总结:对于需要进行居中,而且距离上面元素还有一定的举例,可以设置大元素的内边距。再对元素进行居中。ul在设置的过程中,可能浏览器会默认给ul设置一个padding,需要对其进行清除才能够达到需要的效果。

补充:元素移动不一定需要将其进行定位,使用transform: translateY(30px)。图片覆盖使用:background-size:cover以及contain

17.布局切换(Vue.js)

<body>
    <div id="app" v-cloak>
      <!-- TODO:请在下面实现需求 -->
      <div class="bar">
        <a class="grid-icon" :class="{'active':index===0}" @click="index=0"></a>
        <a class="list-icon" :class="{'active':index===1}" @click="index=1"></a>
      </div>
      <!--grid 示例代码,动态渲染时可删除-->
      <ul class="grid" v-if="index==0">
        <li v-for="(item,index) in goodsList" :key="index">
          <a :href="item.url" target="_blank"> <img :src="item.image.large" /></a>
        </li>
      </ul>
      <ul class="list" v-else>
        <li v-for="(item,index) in goodsList" :key="index">
          <a :href="item.url" target="_blank"> <img :src="item.image.small" /></a>
          <p>{{item.title}}</p>
        </li>
      </ul>
    </div>
  </body>
</html>
<script type="text/javascript">
  var vm = new Vue({
    el: "#app",
    data: {
      goodsList: [],
      index:0
    },
    mounted() {
      // TODO:补全代码实现需求
      axios.get("./goodsList.json").then((res)=>{
        this.goodsList=res.data;
      })
    }
  });
</script>

18.消失的 Token

  <script>
       // TODO 修改下面错误代码
        var app = new Vue({
            el: '#app',
            data() { },
            computed: {
                welcome() {
                    return store.getters.welcome
                },
                username() {
                    return store.state.user.username
                    //return store.getters[`user/username`]
                },
                token() {
                    return store.state.user.token
                       //return store.getters[`user/token`]
                }
            },
            methods: {
                // 回车/点击确认的回调事件
                login(username) {
                    username && store.commit('user/login', { username, token: 'sxgWKnLADfS8hUxbiMWyb' })
                    username && store.commit('say', '登录成功,欢迎你回来!')
                }
            }
        })
    </script>

在这里插入图片描述

19.绝美宋词

<!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" class="search" placeholder="词牌名 词句 词人" v-model="keyword" />
      <ul class="suggestions">
        <li v-for="item in dataList">
          <span class="poet" v-html="highlight(item.poetry_content)"></span>
          <span class="title">
            <span v-html="highlight(item.title)"></span>
            -
            <span v-html="highlight(item.author)"></span>
          </span>
        </li>
      </ul>
    </div>
  </div>
  <script>
    let vm = new Vue({
      el: '#app',
      // TODO:待补充代码
      data() {
        return {
          keyword: '',
          list: [],
        }
      },
      mounted() {
        axios.get('./data.json').then(res => this.list = res.data)
      },
      computed: {
        dataList() {
          return this.keyword ? this.list.filter(e =>
            e.poetry_content.includes(this.keyword) ||
            e.title.includes(this.keyword) ||
            e.author.includes(this.keyword)
          ) : []
        },
      },
      methods: {
        highlight(v) {
          return v.replaceAll(this.keyword, `<span class="highlight">$&</span>`)
        }
      },
    })
  </script>
</body>

</html>

20.成语学习

    getSingleWord(val) {
          let flag = true
          this.idiom.forEach((element,index) => {
            if(element=="" && flag==true){
              this.$set(this.idiom,index,val)
              flag=false
            } 
          });
        }


 confirm() {
          let string=this.idiom.join("");
          var sign=true
          this.arr.forEach(element=> {
            if(element.tip==this.tip && element.word==string ){
              this.result=true
              sign=false
            }
          });
         if(sign){
              this.result=false
            }
        }

将数组转为字符串:使用toString()方法,arr.toString但是结果会以逗号分隔输出。 join()方法:可以在括号里面指定分隔符。

Vue中的 s e t ( ) 方法,给一个响应式对象添加属性的情况, t h i s . set()方法,给一个响应式对象添加属性的情况,this. set()方法,给一个响应式对象添加属性的情况,this.set(this.info, ‘age’ ,24)。这个方法添加三个参数,第一个target:准备添加属性的数组或者对象。第二个参数:name/index:准备添加的属性的属性名或者数字的索引。第三个参数:准备添加的属性的值或者数组索引的值。

使用场景二:

newInfo:[],
info:[
    {
        age:20,
        name:'张三'
    },
    {
        age:30,
        name:'李四'
    },
    {
        age:40,
        name:'王五'
    },
]
this.info.map((item)=>{
this.$set(this.newInfo, item.name, item.age)
})
console.log(this.newInfo)
//[{'张三',20},{'李四',30},{'王五',40}]

注意!!!不能在一个for循环里面放置if以及else,else的语句只能够在for循环外面进行执行。

21.心愿便利贴

<script>
		const app = new Vue({
			el: "#app",
			data: { 
				wishList: [], 
				form: {
					name:'',
					content: '',
					pic: ''
				},
				rules: {
					// TODO 待补充验证的代码
					name: [
					{ required: true, message: '请输入姓名', trigger: 'blur' },
					{ min: 2, max: 5, message: '长度在 2 到 4 个字符', trigger: 'blur' }
				],
				content:[
				   { required: true, message: '请输入许愿内容', trigger: 'blur' },
					{ min: 1, max: 30, message: '长度在 1 到 30 个字符', trigger: 'blur' }
				]
				},
				num:1,
				picList: [],
				textarea: '', 
				dialogVisible: false,
				disabled: false
			},
			methods: { 
				// 提交方法
			  onSubmit() { 
				  this.$refs['form'].validate((valid) => {
					if (valid) {
					  let obj = this.form;
					  obj.css = 'item' + this.num;
					  this.num++;
					  if(this.num > 4) {
						this.num = 1;
					  }
					  this.wishList.push(obj)
					  this.form = {};
					  this.$refs.uploadRef.uploadFiles.pop()  
					  console.log(this.wishList);
					} else { 
					  this.$message({
						message: '提交错误!请检查输入内容',
						type: 'warning'
					  });
					  return false;
					}
				  }); 
			  },
			  // 关闭许愿卡
			  closeCard(index) { 
				  this.wishList.splice(index,1)
			  },
			  // 重置表单
			  onRest() { 
				  this.$refs['form'].resetFields();
			  },
			  // 图片删除
			  handleRemove(file) { 
				  let index = this.$refs.uploadRef.uploadFiles.findIndex(e => e.uid === file.uid);
				  this.$refs.uploadRef.uploadFiles.splice(index,1); 
			  },
			  // 模拟上传图片
			  getPic(e) { 
				  this.form.pic = e.url;
				  this.picList.push(e.url)
			  }, 
			  // 预览图片
			  handlePictureCardPreview(file, fileList) {
				this.form.pic = file.url;
				this.dialogVisible = true;
			  }
			}
		});
	</script>

22 element-ui 组件二次封装

<template>
  <div class="main">
    <el-table
      ref="singleTable"
      highlight-current-row
      :data="tableData"
      stripe
      border
      style="width: 100%"
    >
      <el-table-column label="单选" width="80">
        <!-- TODO:完善单选按钮组件,实现需求(DOM 结构不能修改) -->
        <template slot-scope="scope">
          <el-radio v-model="currentRow" :label="scope.row" @change='change'>&nbsp;</el-radio>
        </template>
      </el-table-column>
      <el-table-column label="日期" width="180">
        <template slot-scope="scope">
          📅<span style="margin-left: 10px">{{ scope.row.date }}</span>
        </template>
      </el-table-column>
      <el-table-column prop="name" label="姓名" width="180"> </el-table-column>
      <el-table-column prop="address" label="地址"> </el-table-column>
    </el-table>
    <div class="tools">
      <el-button @click="setCurrent(tableData[1])">选中第二行</el-button>
      <el-button @click="setCurrent()">取消选择</el-button>
    </div>
  </div>
</template>

<script>
module.exports = {
  props: {
    tableData: {
      type: Array,
      default: () => [],
    },
  },
  data() {
    return {
      currentRow: null,
    };
  },
  methods: {
    setCurrent(row) {
      this.$refs.singleTable.setCurrentRow(row); // 设置当前选中行
      this.change(row)
    },
    change(scope){
      this.currentRow=scope
    }
  },
};
</script>
<style scoped>
.main {
  width: 60%;
  margin: 0 auto;
}
.tools {
  margin-top: 20px;
  text-align: center;
}
</style>

//直接以下这种方式也可以运行。
 <template slot-scope="scope">
     <el-radio v-model="currentRow" :label="scope.$index">&nbsp;</el-radio>
 </template>

23.新年贺卡

document.addEventListener('DOMContentLoaded', function () {
	const greetingDisplay = document.getElementById("greeting-display")
	const btn = document.getElementById("btn")
	// 点击开始书写按钮
	btn.addEventListener("click", () => {
		show(greetingDisplay)
	})
})
const greetings = [
	"新年快乐!",
	"接受我新春的祝愿,祝你平安幸福",
	"祝你新年快乐,洋洋得意!",
	"新的一年,新的开始;心的祝福,新的起点!",
	"新年好!祝新年心情好,身体好,一切顺心!",
]
// 随机数函数 从 greetings 随机取一个值并返回
function writeGreeting() {
	// TODO 带补充代码  
	function getRnd(min,max){
		return Math.floor(Math.random()*(max-min+1))+min
	}
	return greetings[getRnd(0,4)]
}
//  show 将 writeGreeting 函数中返回的内容显示在 greetingDisplay 元素中
function show(greetingDisplay) {
	// TODO 待补充代码
	greetingDisplay.innerHTML=writeGreeting()//在js中获取文本是innerHTML以及innerText
}
module.exports = { show, writeGreeting }

生成一个min-max的随机数,包含边界值。

function getRnd(min,max){
    return Math.floor(Math.random()*(max-min+1))+min
}

Math.floor()函数为向下取整,Math.ceil()函数为向上取整。

在js中获取文本是innerHTML以及innerText

24.用户名片

/*实现上下左右居中*/
方式1:
.center {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%,-50%);
}

方式2:
body {
  display: flex;
  align-items: center;
  justify-content: center;
}
.user-card{
  display: flex;
  align-items: center;
  justify-content: center;
}

总结:第一种方式主要是针对个体整体的位置居中所做的操作,而第二种方式主要是针对某一个个体里面的内容进行居中的操作。

25 芝麻开门

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 div = document.createElement("div");
  // TODO:待补充代码
  div.innerHTML=template
  document.querySelector('body').append(div)
  return new Promise((res,rej)=>{
    document.querySelector("#confirm").addEventListener("click",()=>{
      let word=document.querySelector("input").value;
        res(word)
        document.querySelector(".modal").remove()
    })
    document.querySelector("#cancel").onclick=function(){
      rej(false)
      document.querySelector(".modal").remove()
    }
  })
}

总结:不同于jQuery,可以直接使用$(“”)的方式来进行添加谋某个结构的元素。在js中可以通过先定义模板样式,使用``引入。然后再创建div,在div中通过innerHML的方式来进行写入。再通过append或者appendChild()的方式来添加对应的元素。在使用document.querySelector()的方式进行获取元素的时候,需要使用到.或者#。

在返回一个Promise对象时,需要使用new关键字。

26 随机数生成器

while(arr.length < countNum){
        var num = Math.floor(Math.random() * (max - min + 1) + min)
        if (arr.indexOf(num) === -1){
            arr.push(num)
        }
    }

总结:判断一个数组中是否存在某个元素可以使用includes()方法或者使用indexOf()方法,若返回数字-1,则代表数组中没有包含此元素。

27 时间管理大师

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>任务管理器</title>

<link type="text/css" href="css/style.css" rel="stylesheet" />

</head>
<body>         
<div id="box">
<div class="head">
	<h2>Todos</h2>
	<p>罗列日常计划,做一个时间管理大师!</p>
	<div class="input">
		<span>内容</span>
		<input type="text" placeholder="请输入你要做的事"/>
		<span id='add' @click="add">确认</span>
	</div>
</div>

<ul class="list">
  <li v-if="list.length==0">
  	暂无数据
  </li>
	<li v-for="(element,index) in list" :key="index">
		<!-- 前面的序号 -->
		<span class="xh">{{index+1}}</span>
		<!-- 列表内容 -->
		<span>{{element}}</span>
		<!-- 删除按钮 -->
		<span class="qc" @click="delet(index)"></span>
	</li>
	<li v-if="list.length>0">
		<b>
			总数:{{list.length}}
		</b>
		<b id='clear' @click="remove">清除</b>
	</li>
</ul>
</div>
<script src="js/vue.js"></script>
<script>
var top= new Vue({
	el:"#box",
	data:{
		list:[]
	},
	methods:{
		add(){
			console.log(document.getElementsByTagName('input')[0].value)
			this.list.push(document.getElementsByTagName('input')[0].value)
			console.log(this.list)
		},
		remove(){
			this.list.splice(0,this.list.length)
		},
		delet(index){
			this.list.splice(index,1)
		}
	}
  // 在此处补全代码,实现所需功能
})
</script>
</body>
</html>

总结:有时候题目中的非todo部分也可以进行操作,只要不改变类名等重要信息。有时候题目中存在一部分干扰的代码,需要进行删除之后才能够完成题目。

若想要把数组中的内容全部清空,可以直接将该数组直接赋值为一个空的数组,或者使用splice()方法进行删除,从0 到数组的长度。让元素进行显示和隐藏,除了使用v-show之外,还可以使用v-if,v-if可以直接写出符合显示时的条件。而不需要为其绑复杂的方法。

28 画一只考拉

.face {
  z-index: 1;
  width: 430px;
  height: 380px;
  background: #a0abb6;
  border-radius: 50%;
  align-items: center;

  /* 创造一个网格布局
  6 个纵列(column) --  
    前后两列两等分 (可用 fr 代表一份),
    中间 4 列均为 25px 宽度
  4 个横行(row) -- 
    上下均为 50px,中间两等分
  */
  display: grid;
  grid-template-columns: 1fr repeat(4,25px) 1fr;
  grid-template-rows: 50px 1fr 1fr 50px;
}

.eye {
  /* 
    长为 30px
    高为 30px
    颜色为 #090b0e
    圆角为 50%
    位置居中
  */
  width: 30px;
  height: 30px;
  background-color: #090b0e;
  border-radius: 50%;
  margin: 0 auto;
}

.eye.left {
  /* 按照图示选取 grid-area */
  grid-area: 2/2/3/3;
}

.eye.right {
  /* 按照图示选取 grid-area */
  grid-area: 2/5/3/6;
}

.nose {
  /* 
    高为 100%
    颜色为 #3b464f
    上方圆角为 50%
    下方圆角为 40%
    按照图示选取 grid-area
  */
  height:100%;
  background-color: #3b464f;
  border-top-left-radius: 50%;
  border-top-right-radius: 50%;
  border-bottom-right-radius: 40%;
  border-bottom-left-radius: 40%;
  grid-area: 3/2/4/6;
}

.blush {
  /* 
    长为 40px
    高为 30px
    颜色为 #f6b9bf
    圆角为 50%
  */
  width: 40px;
  height:30px;
  background-color: #f6b9bf;
  border-radius: 50%;
}

.blush.left {
  /* 按照图示选取 grid-area
      并调整位置
   */
   grid-area: 2/1/3/2;
   align-self: end;
   justify-self: end;
}

.blush.right {
  /* 按照图示选取 grid-area
    并调整位置
  */
  grid-area: 2/6/3/7;
  align-self: end;
  justify-self: start;
}

总结:主要考察 Flex 弹性布局和 Grid 网格布局。align-self:定义flex子项单独在侧轴(纵轴)方向上的对其方式。

29 由文本溢出引发的“不友好体验”

  <script>
        // 请在下方补充代码,使得文本溢出 2 行时使用省略号
       var p=document.getElementsByClassName("more2_info_name")[0]
       p.style.overflow="hidden";
       p.style['text-overflow']="ellipsis"//无法表示的属性可以通过['']的方式来进行表述。
       p.style['-webkit-line-clamp']=2
    </script>

使用便捷方式:
 <script>
        // 请在下方补充代码,使得文本溢出 2 行时使用省略号
       var p=document.getElementsByClassName("more2_info_name")[0].style="overflow:hidden;text-overflow:ellipsis;-webkit-line-clamp:2"//直接使用双引号将所有的属性都写入其中,中间使用分号来隔开。
    </script>
/*对于文本一行多余部分使用省略号代替*/
text-overflow:ellipsis;
overflow:hidden;
white-space:nowrap;
/*对于两行或者多行常用 前三行是必须的*/
text-overflow:ellipsis;
overflow:hidden;
-webkit-line-clamp:2;/*行数*/
display:-webkit-box;
-webkit-box-orient:vertical;

30新鲜的蔬菜

在这里插入图片描述

/*方式1:*/
#box1{
  display: flex;
  align-items: center;
  justify-content: center;
}
#box2{
  display: grid;
  grid-template-columns: 68px 68px 68px;/*建议此部分直接使用1fr 1fr 1fr*/
  grid-template-rows: 68px 68px 68px;
 
}
#box2>:last-child{
  grid-area: 3/3/4/4;

}
#box3{
  display: grid;
  grid-template-columns: 68px 68px 68px;
  grid-template-rows: 68px 68px 68px;
}
#box3>:nth-child(2){
  grid-area: 2/2/3/4;

}
#box3>:last-child{
  grid-area: 3/3/4/4;
}

/*方法2:弹性盒子*/
.box {
  display: flex;
}
#box1 {
  flex-direction: row;
  align-items: center;
  justify-content: center;
}
#box2 {
  justify-content: space-between;
}
#box2 .item:nth-child(2) {
  align-self:flex-end;
}
#box3 {
  justify-content: space-between;
}
#box3 .item:nth-child(2) {
  align-self:center;
}
#box3 .item:nth-child(3) {
  align-self:flex-end;
}

justify-content:用于设置或者检索弹性盒子元素在主轴==(横轴)方向上的对其方式==。使用align-content:用于设置在纵轴上的对齐align-self:定义flex子项单独在侧轴(纵轴)方向上的对其方式。

justify-content中:flex-start默认值,整体靠容器左侧对齐。flex-end整体靠容器右侧对齐。center中心。space-between各行之间留有空白。space-around:各行周围留有空白。

align-items用于设置整个容器内所有的元素交叉轴对齐方式,而align-self则是单独某个元素的对齐。

31 为图片添加景深效果

 <script>
      // 请在这里编写代码,根据需求,使得图片达到景深效果
      document.querySelector(".img1").style="-webkit-filter:blur(0px)"
      document.querySelector(".img2").style="-webkit-filter:blur(0px)"
    </script>

//或者
document.querySelector(`.img1`).style.filter = "blur(0)";
document.querySelector(`.img2`).style.filter = "blur(0)";

-webkit-fliter:blur(x px), 若为0px则代表模糊度为0。

32 传送门

主要存在的问题是不知道怎么样获取到元素到窗口顶端的距离。

$(window).scroll(function () {
  // 页面滚动到指定范围,对应的侧边按钮字体变色
  // TODO:请补充代码实现功能
  let h = window.scrollY
  if(h>=1920){
    $("#lift a:nth-of-type(3)").addClass('active-color').siblings().removeClass('active-color')
    // document.querySelectorAll("a")[2].classList.add("active-color")
    // document.querySelectorAll("a")[1].classList.remove("active-color")
    // document.querySelectorAll("a")[0].classList.remove("active-color")
  
  }
 else if(h>=960){
  $("#lift a:nth-of-type(2)").addClass('active-color').siblings().removeClass('active-color')
    // document.querySelectorAll("a")[1].classList.add("active-color")
    // document.querySelectorAll("a")[0].classList.remove("active-color")
    // document.querySelectorAll("a")[2].classList.remove("active-color")
  }
  else{
    $("#lift a:nth-of-type(1)").addClass('active-color').siblings().removeClass('active-color')
  //   document.querySelectorAll("a")[0].classList.add("active-color")
  //  document.querySelectorAll("a")[1].classList.remove("active-color")
  //  document.querySelectorAll("a")[2].classList.remove("active-color")
  }
});
/**
 * @param {Object} scrollTopVal:到达指定位置需要滚动的高度
 * 点击按钮,滚动到指定位置
 */
function toFunction(scrollTopVal) {
  // TODO:请补充代码实现功能
  $(this).addClass("active-color").siblings().removeClass("active-color")
  window.scrollTo(0,scrollTopVal)
}

p:nth-of-type(2)想要找第2次出现p标签的孩子。 p:nth-child(2)想要找到第2个孩子,并且要是p标签下的,若找不到则没有效果。

获取滚动条到页面顶部的距离: let h = window.scrollY。滚动条滚到对应的位置:window.scrollTo(0,scrollTopVal),scrollTopVal为想要滚到的距离。

33 阅读吧

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>阅读吧</title>
    <link rel="stylesheet" href="./css/iconfont/iconfont.css" />
    <link rel="stylesheet" type="text/css" href="./css/index.css" />
  </head>
  <body>
    <div id="app">
      <!-- TODO:请在下面实现需求 -->
      <!-- 设置按钮图标 -->
      <a class="iconfont icon-setting" @click="show=!show"></a>
      <!-- 头部工具栏 -->
      <transition name="fade" v-if="show">
        <div class="header">
          <ul class="tools">
            <li class="container">
              <div class="left">阅读主题</div>
              <!-- 设置主题的圆形色块 -->
              <div class="right" id="setBG">
                <a
                  style="background-color: #f6edd4"
                  :class="{'iconfont icon-selected':index==0}"  @click="add1"
                ></a>
                <a style="background-color: #ebf4ea"  :class="{'iconfont icon-selected':index==1}" @click="add2"></a>
                <a style="background-color: #e9f2f5"  :class="{'iconfont icon-selected':index==2}" @click="add3"></a>
                <a style="background-color: #f6e8e4"  :class="{'iconfont icon-selected':index==3}" @click="add4"></a>
                <a style="background-color: #000000"  :class="{'iconfont icon-selected':index==4}" @click="add5"></a>
              </div>
            </li>
            <li class="container">
              <div class="left">字体大小</div>
              <!-- 设置字体大小的按钮 -->
              <div class="set-font">
                <a class="prev" @click="low">A-</a><b></b> <span class="lang">{{this.number}}</span
                ><b></b>
                <a class="next" @click="add">A+</a>
              </div>
            </li>
            <li class="container">
              <!-- 关闭 x 图标 -->
              <a class="iconfont icon-close" @click="show=!show"></a>
            </li>
          </ul>
        </div>
      </transition>

      <!-- 阅读区 -->
      <p
        class="text-content"
        style="
          background-color: #f6edd4;
          color: #000000;
          font-size: 18px;
          line-height: 28px;
        "
      >
        汪淼觉得,来找他的这四个人是一个奇怪的组合:两名警察和两名军人,如果那两个军人是武警还算正常,但这是两名陆军军官。<br /><br />

        汪淼第一眼就对来找他的警察没有好感。其实那名穿警服的年轻人还行,举止很有礼貌,但那位便衣就让人讨厌了。这人长得五大三粗,一脸横肉,穿着件脏兮兮的皮夹克,浑身烟味,说话粗声大嗓,是最令汪淼反感的那类人。<br /><br />

        “汪淼?”那人问,直呼其名令汪淼很不舒服,况且那人同时还在点烟,头都不抬一下。不等汪淼回答,他就向旁边那位年轻人示意了一下,后者向汪淼出示了警官证,他点完烟后就直接向屋里闯。<br /><br />

        “请不要在我家里抽烟。”汪淼拦住了他。<br /><br />

        “哦,对不起,汪教授。这是我们史强队长。”年轻警官微笑着说,同时对姓史的使了个眼色。<br /><br />

        “成,那就在楼道里说吧。”史强说着,深深地吸了一大口,手中的烟几乎燃下去一半,之后竟不见吐出烟来。“你问。”他又向年轻警官偏了一下头。<br /><br />

        “汪教授,我们是想了解一下,最近你与‘科学边界’学会的成员有过接触,是吧?”<br /><br />

        “‘科学边界’是一个在国际学术界很有影响的学术组织,成员都是著名学者。这样一个合法的学术组织,我怎么就不能接触了呢?”<br /><br />

        “你看看你这个人!”史强大声说,“我们说它不合法了吗?我们说不让你接触了吗?”他说着,刚才吸进肚子里的烟都喷到汪淼脸上。<br /><br />

        “那好,这属于个人隐私,我没必要回答你们的问题。”<br /><br />

        “还啥都成隐私了,像你这样一个著名学者,总该对公共安全负责吧。”史强把手中的烟头扔掉,又从压扁了的烟盒里抽出一根。<br /><br />

        “我有权不回答,你们请便吧。”汪淼说着要转身回屋。<br /><br />

        “等等!”史强厉声说,同时朝旁边的年轻警官挥了一下手,“给他地址和电话,下午去走一趟。”<br /><br />

        “你要干什么!”汪淼愤怒地质问,这争吵引得邻居们也探出头来,想看看出了什么事。<br /><br />

        “史队!你说你――”年轻警官生气地将史强拉到一边,显然他的粗俗不止是让汪淼一人不适应。<br /><br />

        <label>————— 文章摘自著名科幻小说《三体》</label>
      </p>
    </div>
    <script type="text/javascript" src="./js/vue.js"></script>
    <script type="text/javascript">
      // TODO:请在下面实现需求
      new Vue({
        // 注意:请勿修改 data 选项中已提供的数据!!!
        el: "#app",
        data: {
          show:true,
          index:0,
          number:18,
          bgList: ["#f6edd4", "#ebf4ea", "#e9f2f5", "#F6E8E4", "#000000"], // 阅读主题色列表(与设置主题的圆形色块一一对应)
        },
        methods:{
          add1(){
            this.index=0;
            document.querySelector("p").style.backgroundColor=this.bgList[this.index]//为字符串,因此可以之间赋值
            document.querySelector("p").style.color="#333333"
          },
           add2(){
            this.index=1;
            document.querySelector("p").style.backgroundColor=this.bgList[this.index]
            document.querySelector("p").style.color="#333333"

          },
           add3(){
            this.index=2;
            document.querySelector("p").style.backgroundColor=this.bgList[this.index]
            document.querySelector("p").style.color="#333333"
          },
           add4(){
            this.index=3;
            document.querySelector("p").style.backgroundColor=this.bgList[this.index]
            document.querySelector("p").style.color="#333333"
          },
           add5(){
            this.index=4;
            document.querySelector("p").style.backgroundColor=this.bgList[this.index]
            document.querySelector("p").style.color="#ffffff"
          },
          add(){
            var num=document.querySelector("p").style.fontSize;
            num=num.slice(0,-2);
            num=Number(num);
            num=num+2;
            if(num>=48){
              num=48
            }
            this.number=num;
            document.querySelector("p").style.fontSize=`${num}px`
            document.querySelector("p").style.lineHeight=`${num+10}px`
          },
          low(){
            var num=document.querySelector("p").style.fontSize;
            num=num.slice(0,-2);
            num=Number(num);
            num=num-2;
            if(num<=12){
              num=12
            }
            this.number=num;
            document.querySelector("p").style.fontSize=`${num}px`
            document.querySelector("p").style.lineHeight=`${num+10}px`

          }
        }
      });
    </script>
  </body>
</html>

总结:让字符串转为数组使用Number()方法。若某个元素需要点击时触发很多的事件,可以直接绑定一个事件,在事件里面书写所有想要的效果。

34 菜单树检索

存在的问题:一直无法对第二层的内容进行搜索。

 <!-- 需求:输入待查找的字段,输出包含该字段的所有菜单数据。
    1、若该菜单有父级菜单,则返回其父级菜单及同胞菜单。
    2、若该菜单有子级菜单,则返回该菜单及其下子级菜单。
    3、若该菜单既无父级也无子级,则返回菜单本身即可。
    测试字段:查询、首页、管理、配置、维护 -->
		<div id="app">
			<input v-model="search" type="text" placeholder="请输入要搜索的菜单内容"/>
			<ul>
				<li v-for="(element,index) in cartlist" :key="index">  
					<span v-html="lignline(element.meta.title)"></span>
					<ul>
						<li v-for="(item,index) in element.children" :key="index">
							<span v-html="lignline(item.meta.title)"></span>
						</li>
					</ul>
				</li>
			</ul>
		</div>
	</body>
  <script type="text/javascript" src="./js/index.js"></script>
</html>
const app = new Vue({
  el:"#app",
  // 在此处补全代码,实现二级菜单搜索功能
  data:{
    list:[],
    search:''
  },
  computed:{
    cartlist(){
      // 如果搜索值为空则返回全部数据
      if(this.search.length<=0){
        return this.list;
      }else{
       return this.list.filter(item=>{ 
        // 如果一级标签里面有就返回一级标签及其子元素
        if(item.meta.title.includes(this.search)){
          return true;
        }
        // 如果一级标签中没有找到,就在其子元素中找,找到返回给父级
        if(item.children){
        for(let i=0;i<item.children.length;i++){
        if(item.children[i].meta.title.includes(this.search)){
          return true;
        }
       }
        }
        })
      }
    }
  },
  mounted(){
    axios.get("./data.json").then((res)=>{
      this.list=res.data
    })
  },
  methods:{
    lignline(val){
      return val.replaceAll(this.search,`<span style="background-color:yellow">$&</span>`)
    }
  }
});

35 大电影

  <script>
      // 评分星星的 DOM 结构
      let starInerHtml = `<li><img src="images/star.svg" alt=""></li>`;
      for (let index = 0; index < 5; index++) {
        $(".card-body-stars").append(starInerHtml);
      }
      // TODO:待补充代码
      // var xin=document.querySelectorAll(".card-body-option-favorite")
      // console.log(xin)
     $(".card-body-option-favorite img").each(function(i,e){
      e.onclick=function(){
        // console.log($(this).attr("src")=="./images/hollow.svg")
        if($(this).attr("src")=="./images/hollow.svg"){
          $(this).attr("src","./images/solid.svg")
        }else{
          $(this).attr("src","./images/hollow.svg")
        }
        if($(this).attr("src")=="./images/solid.svg"){
          document.getElementById("toast__container").style.display="block"
          document.querySelector(".toast__close").onclick=function(){
            document.getElementById("toast__container").style.display="none"
          }
          setTimeout(()=>{
          document.getElementById("toast__container").style.display="none"
        },2000)
        }
      }
     })
    </script>

jquery css()方法可以取该便签定义的css属性,attr只能获取该标签自带的属性,如img的src属性和alt属性,a链接的href属性。

36 网页PPT

function switchPage() {
  // TODO: 请补充该函数,实现根据activeIndex切换页面的功能,并且在到达最后一页或第一页时给相应的按钮添加disable类
  $("section").each(function(index,element){
    if(index==activeIndex){
      $(element).css("display","block").siblings().css("display","none")
    }
    // $(element).css("display", index !== activeIndex ? 'none' : 'block');
  
  })
  console.log(activeIndex)
  if(activeIndex==0){
    $(".btn.left").addClass("disable")
  }else{
    $(".btn.left").removeClass("disable")
  }
  if(activeIndex==4){
    $(".btn.right").addClass("disable")//class="btn left"获取时中间的空格使用点来代替
  }else{
    $(".btn.right").removeClass("disable")
  }
  $(".page").text(`${activeIndex+1} /5`)
    //document.querySelector(".page").innerText=`${activeIndex+1} /5`
}

37 Vue-Router的基本使用

<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>
    <script src="vue.min.js"></script>
    <script src="vue-router.js"></script>
  </head>

  <body>
    <div id="app">
      <h1>路由的使用</h1>
      <p>
        <!-- 使用 router-link 组件来导航 -->
        <router-link to="/home">首页</router-link>
        <router-link to="/hot">热门</router-link>
        <router-link to="/class">分类</router-link>
      </p>
      <!-- 路由出口 -->
      <!-- 路由匹配到的组件将渲染在这里 -->
      <router-view></router-view>
    </div>
    <script>
      const Home = { template: "<div>首页</div>" };
      const Hot = { template: "<div>热门</div>" };
      const Class = { template: "<div>分类</div>" };

      // 定义路由
      const routes = [
        { path: "/home", component: Home },
        { path: "/hot", component: Hot },
        { path: "/class", component: Class },
      ];

      // 创建 router 实例,然后传 routes 配置
      const router = new VueRouter({
        routes,
      });

      // 创建和挂载根实例
      const app = new Vue({
        router,
      }).$mount("#app");
    </script>
  </body>
</html>

38 学海无涯

   axios.get("./data.json").then((res)=>{
        var arr1=Object.values(res.data.data)[0]
        var arr2=Object.values(res.data.data)[1]
        let list=[];
        let list2=[];
        var sum=0;
        for(var i=0;i<arr1.length;i+=7){
          list.push(arr1.slice(i,7+i))
        }
        for(var i=0;i<arr2.length;i+=7){
          list.push(arr2.slice(i,7+i))
        }
        list.forEach((element,index) => {
          for(var j=0;j<element.length;j++){
            sum=sum+element[j];
          }
          list2.push(sum)
          sum=0
        });
       
        let total1=0;
        let total2=0;
        arr1.forEach(element => {
          total1=total1+element;
        });
        arr2.forEach(element => {
          total2=total2+element;
        });
        option.xAxis.data=['2月第1周','2月第2周','2月第3周','2月第4周','3月第1周','3月第2周','3月第3周','3月第4周','3月第5周']
        option.series[0].data=list2
        myChart.setOption(option);//每一次的数据重新赋值完都需要加上这一句,给mychart添加数据。

        document.querySelector('#week').onclick=function(){
          option.xAxis.data=['2月第1周','2月第2周','2月第3周','2月第4周','3月第1周','3月第2周','3月第3周','3月第4周','3月第5周']
          option.series[0].data=list2
          myChart.setOption(option);//每一次的数据重新赋值完都需要加上这一句,给mychart添加数据。
        }
        document.querySelector("#month").onclick=function(){
          option.xAxis.data=Object.keys(res.data.data)
          option.series[0].data=[total1,total2]
          myChart.setOption(option);//每一次的数据重新赋值完都需要加上这一句,给mychart添加数据。
        }
      })

总结,本道题目主要是在于如何将数据进行获取,以及获取后如何处理,让其可以计算出每个月以及每个星期的总分钟数。

39 天气趋势 A

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>天气趋势</title>
    <meta
      name="viewport"
      content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no"
    />
    <link rel="stylesheet" type="text/css" href="css/style.css" />
    <script src="./js/axios.js"></script>
    <script src="js/vue.min.js" type="text/javascript" charset="utf-8"></script>
    <script
      src="js/echarts.min.js"
      type="text/javascript"
      charset="utf-8"
    ></script>
  </head>

  <body>
    <div id="app">
      <div class="top-bar">2022Y 城全年温度统计图</div>
      <!-- 主体 -->
      <div class="container">
        <!-- 月份 -->
        <div class="month">
          <ul>
            <!-- TODO:待补充代码 在下面的 li 标签中完成 12个月份 (即 monthList) 的渲染  -->
            <li :class="cindex==index? 'active':''" v-for="(item,index) in Object.values(monthList)" :key="index" @click="change(index)">{{item}}</li>
          </ul>
        </div>
        <div class="chart">
          <!-- TODO:待补充代码  -->
          <!-- currentMonth  未来七天和本月 tab 切换,只有当前月才显示 -->
          <div id="currentMonth">
            <div class="title">
              <h3>{{typeTitle}}</h3>
              <div class="type">
                <span id="seven">未来7</span>
                <span id="current">本月</span>
              </div>
            </div>
          </div>
          <div id="chart"></div>
        </div>
      </div>
    </div>
  </body>
</html>
<script>
  // TODO:待补充代码
  var vm = new Vue({
    el: "#app",
    data: {
      chart: null, // 图表
      chartOptions: null, // 图表配置项
      typeTitle: "本月天气",
      monthList: {
        January: "1月",
        February: "2月",
        March: "3月",
        April: "4月",
        May: "5月",
        June: "6月",
        July: "7月",
        August: "8月",
        September: "9月",
        October: "10月",
        November: "11月",
        December: "12月",
      },
      list:[],
      cindex:0,
      xdata:[],
      ydata:[]
    },
    mounted: function () {
      // 初始化 echarts
      axios.get("./js/weather.json").then((res)=>{
        // res.data.forEach(element => {
        //   this.list.push(Object.values(element)[0])
        // });
       this.list=res.data.map(item=>{
        for(const key in item){
          return item[key]
        }
       })
       console.log(this.list)
        this.xdata=this.list[0].length
        this.ydata=this.list[0]

        this.$nextTick(() => {
        this.initChart();
      });
      })
     
    },
    methods: {
      initChart() {
        // 初始化图表
        this.chart = echarts.init(document.getElementById("chart"));
        // 配置项
        this.chartOptions = {
          grid: {
            top: 35,
            bottom: 5,
            left: 10,
            right: 10,
            containLabel: true,
          },
          tooltip: {
            trigger: "axis",
            axisPointer: {
              lineStyle: {
                color: {
                  type: "linear",
                  x: 0,
                  y: 0,
                  x2: 0,
                  y2: 1,
                  colorStops: [
                    {
                      offset: 0,
                      color: "rgba(255,255,255,0)",
                    },
                    {
                      offset: 0.5,
                      color: "rgba(255,255,255,1)",
                    },
                    {
                      offset: 1,
                      color: "rgba(255,255,255,0)",
                    },
                  ],
                  global: false,
                },
              },
            },
          },
          xAxis: [
            {
              type: "category",
              boundaryGap: false,
              axisLabel: {
                formatter: "{value}",
                fontSize: 12,
                margin: 20,
                textStyle: {
                  color: "#bfbfbf",
                },
              },
              axisLine: {
                lineStyle: {
                  color: "#e9e9e9",
                },
              },
              splitLine: {
                show: true,
                lineStyle: {
                  color: "#f7f7f7",
                },
              },
              axisTick: {
                show: false,
              },
              // x 轴显示的数据,日期
              data: this.xdata,
            },
          ],
          yAxis: [
            {
              boundaryGap: false,
              type: "value",
              axisLabel: {
                textStyle: {
                  color: "#bfbfbf",
                },
                formatter: `{value}\u2103`,
              },
              nameTextStyle: {
                color: "#fff",
                fontSize: 12,
                lineHeight: 40,
              },
              splitLine: {
                lineStyle: {
                  color: "#f7f7f7",
                },
              },
              axisLine: {
                show: true,
                lineStyle: {
                  color: "#e9e9e9",
                },
              },
              axisTick: {
                show: false,
              },
            },
          ],
          series: [
            {
              name: "天气",
              type: "line",
              smooth: false,
              showSymbol: false,
              symbolSize: 0,
              zlevel: 3,
              itemStyle: {
                color: "#ff6600",
                borderColor: "#a3c8d8",
              },
              lineStyle: {
                normal: {
                  width: 3,
                  color: "#ff6600",
                },
              },
              areaStyle: {
                normal: {
                  color: new echarts.graphic.LinearGradient(
                    0,
                    0,
                    0,
                    1,
                    [
                      {
                        offset: 0,
                        color: "#ff6600",
                      },
                      {
                        offset: 0.8,
                        color: "#ff9900",
                      },
                    ],
                    false
                  ),
                },
              },
              //  Y 轴显示的数据,即温度数据
              data: this.ydata,
            },
          ],
        };

        // 调用此方法设置 echarts 数据
        this.chart.setOption(this.chartOptions);
      },
      change(index){
        this.cindex=index;
        this.xdata=this.list[index].length
        this.ydata=this.list[index]

        this.$nextTick(() => {
        this.initChart();
      });

      }
    },
  });
</script>

总结:只完成第一二步,.map()可以用来遍历数组中的每个元素,并返回一个新数组,其中包含经过某种处理后的元素。

记住每次对option中的数据进行更改时,需要在后面将配置项进行设置,或者初始化 echarts。本道题存在的问题主要是class绑定的问题。

const numbers=[1,2,3,4,5];
const doubledNumbers=number.map(num=>num*2);
console.log(doubledNumber);//[2,4,6,8,10]

若没有提供axios,则可以采用异步加载的方式来获取数据

$.get(url, data, callback(data, status, xhr), dataType);
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <script src="echarts.js"></script>
    <script src="jquery-3.6.0.min.js"></script>
    <title>异步加载数据</title>
  </head>

  <body>
    <div id="main" style="width:600px; height:400px;"></div>
    <script type="text/javascript">
      var myChart = echarts.init(document.getElementById("main"));
      $.get(
        "data.json",
        function (data) {
          myChart.setOption({
            title: {
              text: "电影类型",
              left: "center",
            },
            tooltip: {
              trigger: "item",
            },
            legend: {
              orient: "vertical",
              left: "left",
            },
            series: [
              {
                type: "pie",
                radius: "55%",
                data: data.data_pie, // 数据
              },
            ],
          });
        },
        "json"
      );
    </script>
  </body>
</html>

40 卡片化标签页

由于是纯js代码实现,因此获取兄弟节点的方式就没有了现成的方法,因此只能够通过较为笨拙的方式将所有的元素列举出来进行设置。

// 实现选项卡功能
function init() {
  // TODO 待补充代码
  var one=document.querySelector("#one");
  var two=document.querySelector("#two");
  var three=document.querySelector("#three");
  var four=document.querySelector("#four");
  document.querySelector(".red").onclick=function(){
    document.querySelector(".red").classList.add("active")
    document.querySelector(".green").classList.remove("active")
    document.querySelector(".blue").classList.remove("active")
    document.querySelector(".yellow").classList.remove("active")
    one.classList.add("active")
    two.classList.remove("active")
    three.classList.remove("active")
    four.classList.remove("active")
  }
  document.querySelector(".green").onclick=function(){
    document.querySelector(".green").classList.add("active")
    document.querySelector(".red").classList.remove("active")
    document.querySelector(".blue").classList.remove("active")
    document.querySelector(".yellow").classList.remove("active")
    one.classList.remove("active")
    two.classList.add("active")
    three.classList.remove("active")
    four.classList.remove("active")
  }
  document.querySelector(".blue").onclick=function(){
    document.querySelector(".blue").classList.add("active")
    document.querySelector(".green").classList.remove("active")
    document.querySelector(".red").classList.remove("active")
    document.querySelector(".yellow").classList.remove("active")
    one.classList.remove("active")
    two.classList.remove("active")
    three.classList.add("active")
    four.classList.remove("active")
  }
  document.querySelector(".yellow").onclick=function(){
    document.querySelector(".yellow").classList.add("active")
    document.querySelector(".green").classList.remove("active")
    document.querySelector(".blue").classList.remove("active")
    document.querySelector(".red").classList.remove("active")
    one.classList.remove("active")
    two.classList.remove("active")
    three.classList.remove("active")
    four.classList.add("active")
  }
}
init();
//其他方式实现
function init() {
  // TODO 待补充代码
  var divs = document.querySelectorAll('.tabs>div');
  var imgs = document.querySelectorAll('#content>div');
  
  for(let i = 0;i<divs.length;i++)//注意:在for中需要使用let,若使用var会产生错误。
  {
    divs[i].onclick=function(){
     for(let a = 0;a<divs.length;a++)
     {
           divs[a].classList.remove('active');
           imgs[a].classList.remove('active');
     } 
            divs[i].classList.add('active');
            imgs[i].classList.add('active');
    }
  }
}
init();

41 偷梁换柱

let person = {
  age: 0,
};
// TODO:在这里写入具体的实现逻辑
// 对 person 的 age 属性更新行为进行拦截
// 如果输入的年龄在 0 - 150 之间,则认为是合法
// 否则,如果小于 0,则返回 0;如果大于 150,则返回 150
person = new Proxy(person,{
  set(target,key,value){
    console.log(target+"-----"+key+"-----"+value);
    value=value > 150?150:value 
    value=value < 0?0:value
    //Reflect.set(target, propertyKey, value[, receiver]),给对象赋值
    return Reflect.set(target,key,value)
  }
})


//方式2:
// 请不要更改这个对象里面的内容
let person = {
  age: 0,
};
// TODO:在这里写入具体的实现逻辑
// 对 person 的 age 属性更新行为进行拦截
// 如果输入的年龄在 0 - 150 之间,则认为是合法
// 否则,如果小于 0,则返回 0;如果大于 150,则返回 150
person=new Proxy(person, {
  get(target, prop) {
    return target[prop] 
  }
  ,
  set(target, prop, val) {
    target[prop] = val < 0 ? 0 : val > 150 ? 150:val
  }
})

总结:get(target, propKey, receiver) target是读取属性的目标对象。propKey是要读取的属性键值。receiver:操作发生的对象。

set(target, propKey, value, receiver) value:要写入的属性值。

42 乾坤大挪移心法

需求比较难理解,主要考察的是ES6语法,…args可以将函数传入的多余参数转换为一个数组,方便在函数内部进行操作。在打印中,重复调用mentalMethods方法,只有最后一次的输入没有传入参数,所以对应得到的数组长度为0,因此可以跟因此而让其输入想要的语句,而其他的情况输入后生成的数组长度大于0的,让其放回自身的方法。

//mentalMethod 需要返回一个函数,可以一直进行调用,但是最后一次调用不传参。
//函数通过以下方式执行,返回结果均为 '战胜峨眉,武当,少林'

function mentalMethod(...args) {
    // TODO 待补充代码  
    if(args.length!=0){
        return mentalMethod
    } 
    else{
        return '战胜峨眉,武当,少林' 
    }
}
console.log(mentalMethod('峨眉')('武当')('少林')());
console.log(mentalMethod('峨眉', '武当')('少林')());
console.log(mentalMethod('峨眉', '武当', '少林')());

43 分阵营,比高低

结果没有问题,但是一直检测发生错误。主要原因,自己给他新添加了一列,这原本就已经有了,因此,添加完之后会发生错误,还有就是排序问题。

function orderStudentGrade(students) {
  // TODO: 在这里写入具体的实现逻辑
  // 将学生的成绩按班级分组,同一班级中按照总分从高到底排序
  let arr1=[];
  let arr2=[];
  let arr3=[];
  students.forEach(element => {
    if(element.class==1){
      arr1.push(element)
    }else if(element.class==2){
      arr2.push(element)
    }else{
      arr3.push(element)
    }
  });
   //可以在最开始时对students数据进行排序,之后再对其进行分班,就不需要分别排序了。
  arr1.sort((a,b)=>(
    (b.math+b.language+b.english+b.physics+b.chemistry)-(a.math+a.language+a.english+a.physics+a.chemistry)
  
  ));
  arr2.sort((a,b)=>(
    (b.math+b.language+b.english+b.physics+b.chemistry)-(a.math+a.language+a.english+a.physics+a.chemistry)
  
  ));
  arr3.sort((a,b)=>(
    (b.math+b.language+b.english+b.physics+b.chemistry)-(a.math+a.language+a.english+a.physics+a.chemistry)
  
  ));
if(students.length==0){
  return {}
}else{
  return {1:arr1,2:arr2,3:arr3}
}

}

module.exports = orderStudentGrade; // 检测需要,请勿删除




//方式2:
if (students.length == 0) return {}
function compare(a, b) {
  const aTotal = a.math + a.language + a.english + a.physics + a.chemistry
  const bTotal = b.math + b.language + b.english + b.physics + b.chemistry
  return bTotal - aTotal
}
const arr1 = students.filter(item => item.class == 1).sort(compare)
const arr2 = students.filter(item => item.class == 2).sort(compare)
const arr3 = students.filter(item => item.class == 3).sort(compare)
console.log(arr1)
return { 1: arr1, 2: arr2, 3: arr3 }

想要根据对象中的数值对其进行排序以及可以使用之前的方式

students.sort((a, b) => (b.math + b.language + b.english + b.physics + b.chemistry) -
    (a.math + a.language + a.english + a.physics + a.chemistry))

补充:箭头函数

//1. 当箭头函数的参数为单个的时候,可以省略包裹参数的小括号。
let func = a => {
  return a;
}
//2. 当 return 后面为单语句时,可以省略 return 和 {} 花括号。
let func = (a) => a;
//3. 如果箭头函数直接返回一个对象,需要用小括号包裹,否则就会报错。
let student = () => ({ name: "小蓝" });

44 水果消消乐

重点:当两个相同的元素出现时,若直接使用display将对应的元素隐藏的话会错位,无法保持原来的位置,因此需要使用opacity来进行设置,让其的透明度为0。当元素出现两个时,需要将其进行判断,则是如果直接判断的话会让第二个元素无法显示出来而是直接消失,因此判断语句放在时间函数里面,将其在一秒后执行。获取分数的值,将其变成数字则是Number()函数。让其进行显示后隐藏除了使用时间函数之外还可以使用动画 $(‘img’).fadeIn(1000).fadeOut(1000);

// TODO:请补充代码
function startGame() {
    $("#start").css("display","none")
    $(".img-box>img").css("display","block")
    setTimeout(()=>{
        $(".img-box>img").css("display","none")
    },1000)
    let arr=[];
   $(".img-box").on('click',function(){
    $(this).children().css("display","block")
    arr.push($(this).children())
    setTimeout(()=>{
        if(arr.length>=2){
            if(arr[0].attr("alt")==arr[1].attr("alt")){
                console.log(arr[0].parent())
                arr[0].parent().css("opacity","0")
                arr[1].parent().css("opacity","0")
                // console.log(Number($("#score").text())+2)  
                $("#score").text(Number($("#score").text())+2) 
            }else{
                arr[0].css("display","none")
                arr[1].css("display","none")
                $("#score").text(Number($("#score").text())-2) 
            }
            arr=[]
        }
    },1000)
   })
   if(arr.length>=2){
    if(arr[0].attr("alt")==arr[1].attr("alt")){
        arr.forEach(element => {
            $(element).parent().css("display","none")
        });
    }else{
        arr.forEach(element => {
            $(element).css("display","none")
        });
    }
    arr=[]
}
}

45 猜硬币

// 将输入的值中 1-9 组成一个数组
function findNum(input_values) {
  // TODO:待补充代码
 //  let result = input_values.match(/[1-9]/g);
  let reg = /\d{1}/;
  let arr = [];
  input_values.split('').forEach(ele=>{
    if(reg.test(ele)){
      arr.push(parseInt(ele));
    }
  })
  console.log(arr);
  return arr
}

// 将 1-9 中三个不重复的随机数放入数组中,并返回这个数组
let randomCoin = () => {
  let randomNumArr = [];
  // TODO:待补充代码
  let arr2=new Set();
  while(arr2.size<3){
    let num=Math.floor(Math.random()*(9-1+1)+1)
    arr2.add(num)
  }
  arr2.forEach(element => {
    randomNumArr.push(element)
    
  });
  return randomNumArr;
};

// 请勿删除和修改下面代码
try {
  module.exports = { randomCoin, findNum };
} catch (e) {}

本次的题目主要存在的问题是对字符串的遍历以及对于数字1-9的判断。字符串的遍历先将其进行逐个地划分,使用split(“”)函数进行划分,之后返回的是数组。

46 小兔子找胡萝卜

// TODO:游戏开始
function start() {
    $("#start").css("display","none")
    $("#move").css("display","block")
}
// TODO:重置游戏
function reset() {
    $("#start").css("display","block")
    $("#reset").css("display","none")
    $(".result").text("")
    $(".container").children(":first").addClass("active").siblings().removeClass("active")
    $("input").val("")

}
// TODO:移动
function move() {
    // console.log($("input").val())
    if($("input").val()==1){   
        $(".result").text("")
        $(".active").next().addClass("active").siblings().removeClass("active");
        if($(".active").children().attr("alt")=="炸弹"){
            $(".result").text("哎呀!兔子踩到炸弹了,游戏结束!")
            $("#move").css("display","none")
            $("#reset").css("display","block")
        }
        if($(".active").children().attr("alt")=="胡萝卜"){
            $(".result").text("小兔子吃到胡萝卜啦,游戏获胜!")
            $("#move").css("display","none")
            $("#reset").css("display","block")
        }
    }else if($("input").val()==2){
        $(".result").text("")
        $(".active").next().next().addClass("active").siblings().removeClass("active");
        if($(".active").children().attr("alt")=="炸弹"){
            $(".result").text("哎呀!兔子踩到炸弹了,游戏结束!")
            $("#move").css("display","none")
            $("#reset").css("display","block")
        }
        if($(".active").children().attr("alt")=="胡萝卜"){
            $(".result").text("小兔子吃到胡萝卜啦,游戏获胜!")
            $("#move").css("display","none")
            $("#reset").css("display","block")
        }
    }else{
        $(".result").text("输入的步数不正确,请重新输入。")
    }
}

总结:jQuery获取输入框中的值使用val(),若想要将其输入框中的值清空,则使用val(“”)。获取下一个兄弟节点使用的方法为next()。获取第一个子元素使用的方法为$().children(“:first”)。若在js中获取input中值使用value,将其清空直接赋值为空。若有很多的元素想要添加事件的话,不能直接获取后就直接赋值,而是需要通过遍历,给它每一个元素添加事件。

47 计算器

// TODO:请补充代码
let formula = document.querySelector('#formula')
let result = document.querySelector('#result')
document.querySelectorAll('.calc-button').forEach((ele) => {
    ele.addEventListener('click', () => {
        if (ele.innerText == '√') return result.value = Math.sqrt(+formula.value)
        if (ele.innerText == '=') return result.value = eval(formula.value.replaceAll('x', '*').replaceAll('÷', '/'))
        if (ele.innerText == 'AC') return formula.value = result.value = ''
        formula.value += ele.innerText
    })
})

48 蓝桥校园一卡通

	submit.onclick = () => {
			// TODO 待补充代码
			let regName=/^[\u4e00-\u9fa5]{2,5}$/ //匹配姓名
            let regId=/^\d{1,12}$/ //匹配学号
			if(!regName.test(studentName.value)){
                studentName.parentNode.classList.add('has-error')
                studentName.nextElementSibling.style.display='block'
                return false
            } else{
                studentName.parentNode.classList.remove('has-error')
                studentName.nextElementSibling.style.display='none'
            }
            if(!regId.test(studentId.value)){
                studentId.parentNode.classList.add('has-error')
                studentId.nextElementSibling.style.display='block'
                return false
            }else{
                studentId.parentNode.classList.remove('has-error')
                studentId.nextElementSibling.style.display='none'
            }
            item[0].innerText ='姓名:' +studentName.value
            item[1].innerText ='学号:'+ studentId.value
            item[2].innerText  = '学院'+college.value
            // 添加 showCard 类显示放大一卡通的动画,请勿删除
		


			// 添加 showCard 类显示放大一卡通的动画,请勿删除
			cardStyle.classList.add('showCard') 
		}
      

补充:

字符描述
\w匹配数字、字母、下划线
\W匹配非数字、字母、下划线
\d匹配数字
\D匹配非数字
\s匹配空白字符(空格、换行)
\S匹配非空白字符
\n匹配换行符
字符描述
*匹配前面的子表达式零次或多次
+匹配前面的子表达式一次或多次
?匹配前面的子表达式零次或一次
{n}匹配确定的 n 次
{n,}至少匹配 n 次
  • 74
    点赞
  • 222
    收藏
    觉得还不错? 一键收藏
  • 55
    评论
提交到GitLab上可以通过以下步骤完成: 1. 首先,进入GitLab网站并登录您的账号。 2. 找到您要提交的项目,并进入该项目的页面。 3. 在项目页面中,点击"Repository"子目录下的"Tags"选项。 4. 在"Tags"页面中,选择"New Tag"按钮。 5. 在"New Tag"页面中,填写"Tag name",可以根据上一次打版的名字进行命名,可以在原有版本号的基础上加1。然后选择"Create from"为"master"分支,填写"Message"作为备注,可以包括日期和时间等信息。最后点击"Create tag"按钮完成标签的创建。 6. 返回项目页面,点击项目名后面的"+"号,选择"This repository"中的"New branch"选项。 7. 在"New branch"页面中,填写"Branch name"为刚才创建的标签名,同时"Create from"也选择刚才创建的标签名。 8. 点击"Create branch"按钮,即可将标签提交到GitLab上。 这样,您就成功将代码提交到GitLab上了。请注意,以上步骤是使用GitLab网站进行提交的方法,如果您使用的是Git小乌龟客户端,可以在客户端中找到相应的操作按钮来完成提交。 #### 引用[.reference_title] - *1* [小乌龟,git使用教程,gitLab打版教程](https://blog.csdn.net/qq_41893686/article/details/126610292)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 55
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值