为了复习一下原生JS和CSS,做了一个九宫格的小练习👀。

1. 效果

点击开始闪烁,九宫格中的三个格子获取不同颜色;
点击结束闪烁,九宫格中的格子不再获取其它颜色。

在线演示

2. 实现

2.1 布局

首先要使用HTML+CSS将这个九宫格页面制作出来。

  • <!DOCTYPE>不是HTML标签,是指示浏览器该页面使用哪个HTML版本进行编写的指令。
  • 尽量不要使用table来形成这种网格布局。

这里使用弹性布局来进行整个页面的布局。

  1. 采用弹性布局的元素,称为弹性容器。其子元素为弹性项目(Flex Items)
  2. flex-wrap: wrap 弹性项目一行排不下则进行换行,不在一行进行排列
  3. justify-content 项目横向居中
  4. align-items 项目纵向居中

另外,还是用了@media使移动端也进行适配。


表示当屏幕最大宽度小于768px时,修改下面设定的样式。

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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>九宫格</title>
<link rel="stylesheet" href="./me.css" type="text/css">
<link rel="icon" href="./favicon.ico">
</head>
<body>
<div class="box-wrap">
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
</div>
<div class="button-wrap">
<input type="button" value="开始闪烁" onclick="startFlash()">
<input type="button" value="结束闪烁" onclick="endFlash()">
</div>
<script src="./me.js"></script>
</body>
</html>
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
.box-wrap {
background-color: #d4d4f5;
width: 500px;
height: 500px;
margin: 50px auto 10px auto;
display: flex;
flex-wrap: wrap;
justify-content: center;
align-items: center;
border-radius: 2%;
}

.box {
width: 29%;
height: 29%;
display: inline-block;
border-radius: 10%;
background-color: orange;
text-align: center;
margin: 1%;
}

.button-wrap {
width: 500px;
height: 100px;
margin: auto;
}

.button-wrap input {
width: 100%;
height: 50%;
margin-bottom: 10px;
font-size: large;
border-style: none;
border-radius: 15px;
color: orange;
outline: none;
transition: background-color 0.3s;
cursor: pointer;
}

.button-wrap input:focus, .button-wrap input:hover {
background-color: orange;
color: white;
}

/* mobile */
@media screen and (max-width: 768px) {
.box-wrap {
background-color: #d4d4f5;
width: 400px;
height: 400px;
margin: 50px auto 10px auto;
display: flex;
flex-wrap: wrap;
justify-content: center;
align-items: center;
border-radius: 2%;
}
.button-wrap {
width: 400px;
height: 100px;
margin: auto;
}
}

2.2 逻辑

JS在这里实现点击后的操作以及修改九宫格块的颜色。

问题:

  1. 从9个box中,随机挑选三个上色,需要实现从0-8中,随机获取三个不同的随机数的函数。
  2. 获取随机颜色的函数。
  3. 实现点击后连续闪烁,直至点击停止闪烁后才停止。

1 获取随机数:

首先新建一个数组,大小为9,其中的数字分别是0-8.利用Math.floor(Math.random()*8)得到0-8的一个随机数,将这个随机数作为索引,将数组对应的值放入结果数组,然后删除选取过的这个值。直到结果数组的长度为3,停止选取。

array.splice(index, howmany) 删除数组中对应index的元素,howmany表示删除元素的个数,这个操作会影响原数组。
array.slice(start, end) 从已有数组中返回选定的元素,不会修改数组,而是返回一个新数组。

2 获取随机颜色:

利用随机数产生0-ffff的一个随机数,然后转换为16进制的字符串即可。

3 连续闪烁

使用BOM中的setInterval(task, time), clearInterval(), 时间以毫秒为单位。

定时器返回一个id,将这个id传给clearInterval可以清除对应的定时器👍

这里的定时器是从一个函数启动,再另一个函数中关闭的。所以设置一个全局变量,来实现这个操作。

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
// 定义全局变量 方便结束定时器
var task = null;

const startFlash = () => {
task = setInterval(flash, 500);
}

const endFlash = () => {
clearInterval(task);
const elements = document.getElementsByClassName("box");
for (let i = 0; i < elements.length; i++) {
elements[i].style.backgroundColor = "orange";
}
}

const flash = () => {
const elements = document.getElementsByClassName("box");
const randomNum = getRandomNum(3);
for (let i = 0; i < elements.length; i++) {
elements[i].style.backgroundColor = "orange";
}
for (let i = 0; i < randomNum.length; i++) {
const element = elements[randomNum[i]];
element.style.backgroundColor = getRandomColor();
}
}

const getRandomColor = () => {
return '#' + Math.floor( Math.random() * 0xffffff ).toString(16);
}

const getRandomNum = (n) => {
const res = [];
const arr = [];
for (let i = 0; i < 9; i++) {
arr[i] = i;
}
while (true) {
const index = Math.floor(Math.random() * 8);
if (arr[index] == undefined) continue;
res.push(arr[index]);
arr.splice(index, 1);
if (res.length == n) break;
}
return res;
}

3. 总结

对CSS布局更加了解了😂,再好好体会JS中函数也可以作为表达式赋值给常量的思想🤣