视频讲解:点击观看

01 水果拼盘(5分)

查看样式可以看到,所有水果都放在了 #pond 元素中,由于只设置了 display: flex;,导致所有水果都处于一行。

因此,我们只需设置主轴方向为纵向 、并允许换行即可:

1
2
3
4
5
/* TODO:待补充代码 */
#pond {
flex-direction: column;
flex-wrap: wrap;
}

02 展开你的扇子(5分)

查看源码可以看到,页面有 12 个相同大小的 div 元素,要求前 6 个顺时针转动,后 6 个逆时针转动。

转动动画用到了 transform: rotate(10deg); 这个属性:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
/*TODO:请补充 CSS 代码*/
#box:hover #item6 {
transform: rotate(-10deg);
}
#box:hover #item5 {
transform: rotate(-20deg);
}
#box:hover #item4 {
transform: rotate(-30deg);
}
#box:hover #item3 {
transform: rotate(-40deg);
}
#box:hover #item2 {
transform: rotate(-50deg);
}
#box:hover #item1 {
transform: rotate(-60deg);
}
#box:hover #item7 {
transform: rotate(10deg);
}
#box:hover #item8 {
transform: rotate(20deg);
}
#box:hover #item9 {
transform: rotate(30deg);
}
#box:hover #item10 {
transform: rotate(40deg);
}
#box:hover #item11 {
transform: rotate(50deg);
}
#box:hover #item12 {
transform: rotate(60deg);
}

03 和手机相处的时光(10 分)

这是道代码修复题:由说明可知,文件里 var option = {} 中的内容是 ECharts 的配置项,该配置中存在 Bug,导致坐标轴显示不正确。

Echarts 官方示例 中的代码作比较,我们可以发现是由于 xAxisyAxis 配置项中的 type 值反了,导致两个轴的显示不正常。X 轴应该是 type: "category",,Y 轴应该是 type: "value",

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<script>
var chartDom = document.getElementById("main");
var myChart = echarts.init(chartDom);
/*TODO:ECharts 的配置中存在错误,请改正*/
var option = {
title: {
text: "一周的手机使用时长",
},
xAxis: {
// type: "value",
type: "category",
data: ["周一", "周二", "周三", "周四", "周五", "周六", "周日"],
},
yAxis: {
// type: "category",
type: "value",
},
series: [
{
data: [2.5, 2, 2.6, 3.2, 4, 6, 5],
type: "line",
},
],
};
myChart.setOption(option);
</script>

04 灯的颜色变化(10 分)

通过查看源码我们可知,三个颜色的灯泡是已经在页面中给出了的,只是红灯和绿灯被 display: none; 掉了。

因此我们可以通过定时器来实现描述效果,一个等待 3 秒,一个等待 6 秒:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// TODO:完善此函数 显示红色颜色的灯
function red() {
setTimeout(() => {
// console.log('red')
document.querySelector("#defaultlight").style.display = 'none'
document.querySelector("#redlight").style.display = 'inline-block'
}, 3000);
}

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

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

trafficlights();

或者如果想用 Promise 实现异步任务,但注意此时都是等待 3 秒。因为当 red() 执行成功后,才会继续执行 green()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// TODO:完善此函数 显示红色颜色的灯
function red() {
return new Promise((resolve, reject) => {
setTimeout(() => {
// console.log('red')
document.querySelector("#defaultlight").style.display = 'none'
document.querySelector("#redlight").style.display = 'inline-block'
resolve()
}, 3000);
})
}

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

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

trafficlights();

05 东奥大抽奖(15 分)

阅读源码我们可知,每次点击按钮后会生成随机20-30次的转动次数,然后会调用 rolling() 函数转起来。

根据要求,我们要补全的代码需要实现:点击开始后,以 classli1 的元素为起点,黄色背景(.active 类)在奖项上顺时针转动。当转动停止后,将获奖提示显示到页面的 idaward 元素中。

  • 我们定义一个变量 num,用来表示高亮索引,也就是控制 li1 ~ li8 哪个奖品高亮。在递归函数中,随着转动次数的增加,索引值也是增加的。但是当索引值大小超过 8 的时候,我们要将其重置为 1:

    1
    2
    3
    4
    5
    6
    7
    time++; // 转动次数加1

    num++; // 高亮索引加1
    if(num > 8) {
    num = 1
    }
    // console.log(time, num)
  • 然后用 jQuery 在递归函数中,选中类名为 li+num 的元素,给当前索引的奖品添加 active 类名:

    1
    $('.li' + num).addClass('active')
  • 同时移除它的同胞元素的 active 类名:

    1
    $('.li' + num).addClass('active').siblings().removeClass('active');

    其中 siblings() 是 jQuery 中的方法,用于查找当前元素的所有同胞元素,也就是有相同类名的同胞元素。

    注意 addClass()removeClass 都是 jQuery 中的方法,用于添加和移除 Dom 元素的指定类名。如果要用原生 JS 语法实现,可以使用 classList.add()classList.remove() 方法。例如,下面的代码可以实现上方 jQuery 代码相同的效果:

    1
    2
    3
    4
    5
    6
    document.querySelectorAll('.li' + num).forEach(function(el) {
    el.classList.add('active');
    el.parentNode.querySelectorAll(':scope > li:not(.li' + num + ')').forEach(function(sibling) {
    sibling.classList.remove('active');
    });
    });

    这里使用了 querySelectorAll() 方法来选中类名为 li+num 的元素,得到只有当前元素的 NodeList 节点数组,然后使用 forEach() 方法遍历该数组。在遍历过程中,使用 classList.add() 方法为当前元素添加类名,使用 parentNode 属性和 querySelectorAll() 方法查找当前元素的同胞元素,并使用 classList.remove() 方法移除它们的类名。

    显然,使用 jQuery 可以大大减少代码量。

  • 接下来要做的就是在转动停止后,将抽奖结果放到 idaward 元素中。

    1
    $('#award').text(`恭喜您抽中了${$('.li' + num).text()}!!!`);

    jQuery 的 .text() 方法相当于原生 JS 中的 .textText 属性,而不是 .innerHTML 属性。因为 .text() 方法和 .textText 属性只会显示文本内容,不会解析 HTML 标记。

  • 最后别忘了重置高亮索引,以便于下次抽奖时还是从第一个商品开始转动。

    1
    2
    3
    4
    5
    6
    7
    8
    // time > times 转动停止
    if (time > times) {
    clearInterval(rollTime);
    $('#award').text(`恭喜您抽中了${$('.li' + num).text()}!!!`);
    time = 0;
    num = 0; // 重置高亮索引
    return;
    }

至此,本题完成,完整代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
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++; // 高亮索引加1
if (num > 8) {
num = 1
}
// console.log(time, num)

clearTimeout(rollTime);
rollTime = setTimeout(() => {
window.requestAnimationFrame(rolling); // 进行递归动画
}, speed);

$('.li' + num).addClass('active').siblings().removeClass('active');
// document.querySelectorAll('.li' + num).forEach(function (el) {
// el.classList.add('active');
// el.parentNode.querySelectorAll(':scope > li:not(.li' + num + ')').forEach(function (sibling) {
// sibling.classList.remove('active');
// });
// });

// time > times 转动停止
if (time > times) {
clearInterval(rollTime);
$('#award').text(`恭喜您抽中了${$('.li' + num).text()}!!!`);
time = 0;
num = 0; // 重置高亮索引
return;
}
}

06 蓝桥知识网(15 分)

这是道页面布局题,注意页面版心宽度为 1024px,要保证版心居中。

  • 首先清除一下默认样式,然后设置一个版心类:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    * {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
    }

    li {
    list-style: none;
    }

    /* 版心 */
    .wrap {
    width: 1024px;
    margin: 0 auto;
    }
  • 布局 header 部分:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    <!-- 头部 start -->
    <header>
    <div class="wrap">
    <div class="nav">
    <h1>蓝桥知识网</h1>
    <ul>
    <li>首页</li>
    <li>热门技术</li>
    <li>使用手册</li>
    <li>知识库</li>
    <li>练习题</li>
    <li>联系我们</li>
    <li>更多</li>
    </ul>
    </div>
    <div class="container">
    <div class="title">蓝桥云课</div>
    <div class="text">随时随地丰富你的技术栈!</div>
    <div class="join">加入我们</div>
    </div>
    </div>
    </header>
    <!-- 头部 end -->
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    /* header */

    header {
    padding-top: 13px;
    background-color: #a6b1e1;
    }

    header .nav {
    height: 46px;
    display: flex;
    justify-content: space-between;
    }

    header .nav h1 {
    font-size: 18px;
    color: white;
    margin-right: 365px;
    }

    header .nav ul {
    display: flex;
    }

    header .nav ul li {
    margin-right: 16px;
    font-size: 16px;
    color: white;
    }

    header .container {
    height: 427px;
    text-align: center;
    }

    header .container .title {
    margin-top: 30px;
    font-size: 45px;
    color: black;
    }

    header .container .text {
    margin-top: 62px;
    color: white;
    font-size: 21px;
    font-weight: 200;
    }

    header .container .join {
    margin: 36px auto 0;
    color: #efbfbf;
    border-radius: 2px;
    font-size: 18px;
    box-shadow: inset 0 0 0 2px #efbfbf;
    /* 以下为目测 */
    width: 120px;
    height: 50px;
    line-height: 50px;
    }
  • 布局 main 部分:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    <!-- 主体 start -->
    <main>
    <div class="wrap">
    <ul>
    <li>
    <div class="info-title">人工智能</div>
    <div class="info-content">人工智能亦称智械、机器智能,指由人制造出来的机器所表现出来的智能。通常人工智能是指通过普通计算机程序来呈现人类智能的技术。</div>
    </li>
    <li>
    <div class="info-title">前端开发</div>
    <div class="info-content">前端开发是创建 WEB 页面或 APP 等前端界面呈现给用户的过程,通过 HTML,CSS 及 JavaScript 以及衍生出来的各种技术、框架、解决方案,来实现互联网产品的用户界面交互。</div>
    </li>
    <li>
    <div class="info-title">后端开发</div>
    <div class="info-content">后端开发是实现页面的交互逻辑,通过使用后端语言来实现页面的操作功能,例如登录、注册等。</div>
    </li>
    <li>
    <div class="info-title">信息安全</div>
    <div class="info-content">ISO(国际标准化组织)的定义为:为数据处理系统建立和采用的技术、管理上的安全保护,为的是保护计算机硬件、软件、数据不因偶然和恶意的原因而遭到破坏、更改和泄露。</div>
    </li>
    </ul>
    </div>
    </main>
    <!-- 主体 end -->
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    /* main */
    main {
    margin-top: 74px;
    height: 302px;
    }

    main .wrap ul {
    display: flex;
    flex-wrap: wrap;
    }

    main .wrap ul li {
    width: 50%;
    height: 144px;
    padding-right: 20px;
    }

    main .wrap ul li .info-title {
    font-size: 30px;
    font-weight: 200;
    columns: black;
    }

    main .wrap ul li .info-content {
    font-size: 18px;
    color: #aaa;
    line-height: 1.4em;
    /* 以下为目测 */
    margin-top: 20px;
    margin-bottom: 20px;
    }
  • 布局 footer 部分:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    <!-- 页尾 start -->
    <hr />
    <footer>
    <div class="wrap">
    <div class="footer-title">© 蓝桥云课 2022</div>
    <div class="footer-info">京公网安备 11010102005690 号 | 京 ICP 备 2021029920 号</div>
    </div>
    </footer>
    <!-- 页尾 end -->
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    /* footer */
    footer {
    height: 80px;
    text-align: center;
    font-size: 14px;
    color: #aaa;
    }

    footer .wrap .footer-title {
    margin-top: 30px;
    }

    footer .wrap .footer-info {
    margin-top: 10px;
    }

07 布局切换(20 分)

  • 在线环境 - 蓝桥杯题库2454

  • 考点:Vue 2.xaxios

  • 我们先根据要求实现按钮颜色的动态切换,即通过 active 类名的添加和移除来实现:

    1
    2
    3
    4
    5
    <!-- 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>
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    <script type="text/javascript">
    var vm = new Vue({
    el: "#app",
    data: {
    goodsList: [],
    index: 0,
    },
    mounted() {
    // TODO:补全代码实现需求
    },
    });
    </script>
  • 首先完成数据请求(数据来源 goodsList.json

    1
    2
    3
    4
    5
    axios.get('./goodsList.json')
    .then(res => {
    // console.log(res)
    this.goodsList = res.data
    })
  • 通过阅读源码我们可知 <ul class="grid"><ul class="list"> 是互斥事件,因此可以用 v-if 来动态渲染。在其中分别使用 v-for 渲染出请求回来的数据项。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    <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-if="index === 1">
    <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>

检测通过,本题完成,完整代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8" />
<title>布局切换</title>
<script type="text/javascript" src="./js/vue.js"></script>
<link rel="stylesheet" type="text/css" href="./css/index.css" />
<script src="./js/axios.min.js" type="text/javascript" charset="utf-8"></script>
</head>

<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-if="index === 1">
<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 => {
// console.log(res)
this.goodsList = res.data
})
},
});
</script>

08 购物车(20 分)

  • 在线环境 - 蓝桥杯题库2455

  • 考点:Vue 2.xJS 数组 push/splice 方法

  • 可以看到,当前代码中 addToCartremoveGood 方法是不完美的。

    1
    2
    3
    4
    5
    6
    7
    addToCart(goods) {
    // TODO:修改当前函数,实现购物车加入商品需求

    goods.num = 1;
    this.cartList.push(goods);
    this.cartList = JSON.parse(JSON.stringify(this.cartList));
    },

    addToCart 中,我们需要先判断购物车列表中有没有该商品,才能选择是 添加该商品 还是 在购物车该商品原数量上加1

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    addToCart(goods) {
    // TODO:修改当前函数,实现购物车加入商品需求
    let hasGoods = false;
    // 遍历查找购物车列表中是否存在该商品
    this.cartList.forEach(item => {
    if(item.id === goods.id) {
    item.num++
    hasGoods = true;
    }
    });
    if (!hasGoods) {
    goods.num = 1;
    this.cartList.push(goods);
    }

    this.cartList = JSON.parse(JSON.stringify(this.cartList));
    },

    至此,“加入购物车”以及加号按钮功能正常。

  • 但是对于移除购物车函数 removeGoods 来说,就不用判断购物车列表是否有该商品了,因为既然你都可以点击减号按钮了,说明该商品已经在购物车了呀!

    1
    2
    3
    4
    5
    6
    7
    8
    9
    removeGoods(goods) {
    // TODO:补全代码实现需求
    this.cartList.forEach(item => {
    // 遍历查找购物车列表,直到找到该商品
    if(item.id === goods.id) {
    item.num--
    }
    })
    }

    现在就实现了点击减号按钮,减少该商品在购物车中的数量了。

  • 但别忘了当数量减少到 0 的时候从购物车移除该商品:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    removeGoods(goods) {
    // TODO:补全代码实现需求
    this.cartList.forEach((item, index) => {
    // 遍历查找购物车列表,直到找到该商品
    if(item.id === goods.id) {
    item.num--
    if(item.num <= 0) {
    this.cartList.splice(index, 1)
    }
    }
    })

    this.cartList = JSON.parse(JSON.stringify(this.cartList));
    }

    其中最后一句 this.cartList = JSON.parse(JSON.stringify(this.cartList)); 是对 cartList 进行一次深拷贝,防止干扰之后的一些操作。说实话我没太理解这一步操作,我感觉不进行这次拷贝也能正常工作,感觉这行代码是句废话。

    问了一下 NewBing 是这样回答我的:这行代码的意义是将 this.cartList 对象进行深拷贝,然后将拷贝后的对象重新赋值给 this.cartList 对象。这样做的目的是为了避免直接修改 this.cartList 对象时,对其他引用该对象的变量造成影响。如果不进行深拷贝,直接将 this.cartList 赋值给其他变量,那么修改其中一个变量的值会影响到其他变量的值。所以这行代码并不是多此一举,而是为了保证程序的正确性。

    但是…似乎…这道题中不拷贝也不会有啥影响吧……

完整的代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
<!DOCTYPE html>
<html>

<head lang="en">
<meta charset="UTF-8">

<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
<title>购物车</title>
<script src="./js/goods.js"></script>
<script type="text/javascript" src="./js/vue.js"></script>
<link href="./css/index.css" rel="stylesheet" type="text/css" />
</head>

<body>
<div id="app">
<!-- 商品列表 -->
<h3>商品列表</h3>
<ul id="goodsList">
<template v-for="goods in goodsList">
<li class="goods-item" :key="goods.id">
<div><img :src="goods.imgUrl" /> </div>
<div>{{goods.name}}</div>
<div>¥ {{goods.price}} </div>
<button @click="addToCart(goods)">加入购物车</button>
</li>
</template>
</ul>
<!-- 购物车 -->
<template v-if="cartList.length>0">
<h3>购物车</h3>
<ul id="cartList">
<template v-for="goods in cartList">
<li class="goods-item" :key="goods.id">
<div><img :src="goods.imgUrl" /> </div>
<div>{{goods.name}}</div>
<div>¥ {{goods.price}} </div>
<div class="item-control">
<button @click="removeGoods(goods)">-</button>
<h4>{{goods.num}}</h4>
<button @click="addToCart(goods)">+</button>
</div>
</li>
</template>
</ul>
</template>
</div>
</body>

</html>

<script>
new Vue({
el: '#app',
data: {
cartList: [],
goodsList: []
},
mounted() {
this.goodsList = GoodsArr;
},
methods: {
addToCart(goods) {
// TODO:修改当前函数,实现购物车加入商品需求
let hasGoods = false;
// 遍历查找购物车列表中是否存在该商品
this.cartList.forEach(item => {
if(item.id === goods.id) {
item.num++
hasGoods = true;
}
});
if (!hasGoods) {
goods.num = 1;
this.cartList.push(goods);
}

this.cartList = JSON.parse(JSON.stringify(this.cartList));
},
removeGoods(goods) {
// TODO:补全代码实现需求
this.cartList.forEach((item, index) => {
// 遍历查找购物车列表,直到找到该商品
if(item.id === goods.id) {
item.num--
if(item.num <= 0) {
this.cartList.splice(index, 1)
}
}
})

this.cartList = JSON.parse(JSON.stringify(this.cartList));
}
}
});
</script>

09 寻找小狼人(25 分)

根据题目要求,我们需要实现类似数组的 filter 方法, 返回一个都是狼人的新数组:

1
cardList.filter((item) => item.category == "werewolf")

阅读源码我们可知要手写的这个 myarray 方法的调用方式是:

1
2
3
let newcardList = cardList.myarray(
(item) => item.category == "werewolf"
);

因此该方法需要挂载到数组的原型上,文件中已经给我们提供好了,只需完善即可:

1
2
3
4
// 返回条件为真的新数组
Array.prototype.myarray = function (cb) {
// TODO:待补充代码
};

我们需要知道的是,传入的 cb 回调函数的返回值是布尔值,我们需要使用这个函数来过滤数组。此外,还需要知道,在我们要手写的 myarray 这个函数中,this 的值就是调用此函数的那个数组。

本题完整代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 返回条件为真的新数组
Array.prototype.myarray = function (cb) {
// TODO:待补充代码
// cb(); // boolean
let newArr = [];
let arr = this; // this是调用此方法的那个数组
for (let i = 0; i < arr.length; i++) {
if (cb(arr[i])) {
newArr.push(arr[i]);
}
}

return newArr;
};

10 课程列表(25 分)

  • 在线环境 - 蓝桥杯题库2457

  • 考点:手写分页组件、axios.slice(0, 5).map().join().toFixed(2)

  • 我们首先实现数据请求,通过总数据计算出总页数,并把总页数和当前页数在前端页面显示出来:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    let pageNum = 1; // 当前页码,默认页码1
    let maxPage; // 最大页数

    // TODO:待补充代码

    // 显示当前页码
    function showPagination(maxPage, pageNum) {
    document.querySelector('#pagination').innerHTML = `共${maxPage}页,当前${pageNum}页`
    }

    // 数据请求
    let data; // 总数据
    let pageData; // 每页数据
    axios.get('./js/carlist.json')
    .then(res => {
    // console.log(res)
    data = res.data
    maxPage = Math.ceil(data.length / 5)
    // 显示当前页码
    showPagination(maxPage, pageNum);
    })
  • 根据当前页数从总数据中获取当页数据,并渲染在页面上 :

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    let pageNum = 1; // 当前页码,默认页码1
    let maxPage; // 最大页数

    // TODO:待补充代码

    // 显示当前页码
    function showPagination(maxPage, pageNum) {
    document.querySelector('#pagination').innerHTML = `共${maxPage}页,当前${pageNum}页`
    }

    // 获得每页数据
    function getPageData(data) {
    return data.slice((pageNum - 1) * 5, pageNum * 5)
    }

    // 渲染每页数据
    function renderHTML(pageData) {
    document.querySelector('#list').innerHTML = pageData.map(item => `
    <div class="list-group">
    <a href="#" class="list-group-item list-group-item-action">
    <div class="d-flex w-100 justify-content-between">
    <h5 class="mb-1">${item.name}</h5>
    <small>${(item.price / 100).toFixed(2)}元</small>
    </div>
    <p class="mb-1">
    ${item.description}
    </p>
    </a>
    </div>
    `).join();
    }

    // 数据请求
    let data; // 总数据
    let pageData; // 每页数据
    axios.get('./js/carlist.json')
    .then(res => {
    // console.log(res)
    data = res.data
    maxPage = Math.ceil(data.length / 5)
    // 显示当前页码
    showPagination(maxPage, pageNum);
    // 获得每页数据
    pageData = getPageData(data);
    // 渲染每页数据
    renderHTML(pageData);
    })
  • 然后是实现翻页按钮功能,注意要做边界控制:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    // 点击上一页
    let prev = document.getElementById("prev");
    prev.onclick = function () {
    // TODO:待补充代码
    next.classList.remove('disabled')
    pageNum--
    console.log(pageNum)
    if (pageNum <= 1) {
    this.classList.add('disabled')
    pageNum = 1
    }

    // 显示当前页码
    showPagination(maxPage, pageNum);
    // 获得每页数据
    pageData = getPageData(data);
    // 渲染每页数据
    renderHTML(pageData);
    };
    // 点击下一页
    let next = document.getElementById("next");
    next.onclick = function () {
    // TODO:待补充代码
    prev.classList.remove('disabled')
    pageNum++
    console.log(pageNum)
    if (pageNum >= maxPage) {
    this.classList.add('disabled')
    pageNum = maxPage
    }

    // 显示当前页码
    showPagination(maxPage, pageNum);
    // 获得每页数据
    pageData = getPageData(data);
    // 渲染每页数据
    renderHTML(pageData);
    };