ZhangYang's Blog

【实战】IFE的JavaScript编码

任务一

任务目的

JavaScript初体验

初步明白JavaScript的简单基本语法,如变量、函数

初步了解JavaScript的事件是什么

初步了解JavaScript中的DOM是什么

任务描述

用户可以在输入框中输入任何内容,点击“确认填写”按钮后,用户输入的内容会显示在“您输入的值是”文字的右边

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>
<head>
<meta charset="utf-8">
<title>IFE JavaScript Task 01</title>
</head>
<body>
<label>请输入北京今天空气质量:<input id="aqi-input" type="text"></label>
<button id="button">确认填写</button>
<div>您输入的值是:<span id="aqi-display">尚无录入</span></div>
<script type="text/javascript">
(function() {
/*
在注释下方写下代码
给按钮button绑定一个点击事件
在事件处理函数中
获取aqi-input输入的值,并显示在aqi-display中
*/
})();
</script>
</body>
</html>

注意事项

实现简单功能的同时,请仔细学习JavaScript基本语法、事件、DOM相关的知识

请注意代码风格的整齐、优雅

代码中含有必要的注释

可以不考虑输入的合法性

建议不使用任何第三方库、框架

示例代码仅为示例,可以直接使用,也可以完全自己重写

参考资料

JavaScript入门篇

MDN JavaScript

任务代码

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
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>IFE JavaScript Task 01</title>
</head>
<body>
<label>请输入北京今天空气质量:<input id="aqi-input" type="text"></label>
<button id="button">确认填写</button>
<div>您输入的值是:<span id="aqi-display">尚无录入</span></div>
<script type="text/javascript">
(function() {
/*
在注释下方写下代码
给按钮button绑定一个点击事件
在事件处理函数中
获取aqi-input输入的值,并显示在aqi-display中
*/
var $ = function(id){
return document.getElementById(id)
}
var hander = function(){
var num = parseInt($('aqi-input').value)
if ((!isNaN(num)) && (num >= 0) && (num <=1000)) {
$("aqi-display").innerHTML = num;
}else{
alert($('aqi-input').value + " 不是有效的空气质量数值,请重新输入0-1000的有效整数!")
}
}
$('button').onclick = function(){
hander()
}
$('aqi-input').onkeyup = function(event){
if (event.keyCode === 13) {
hander()
}
}
})();
</script>
</body>
</html>

任务二

任务目的

在上一任务基础上继续JavaScript的体验

学习JavaScript中的if判断语法,for循环语法

学习JavaScript中的数组对象

学习如何读取、处理数据,并动态创建、修改DOM中的内容

任务描述

参考以下示例代码,页面加载后,将提供的空气质量数据数组,按照某种逻辑(比如空气质量大于60)进行过滤筛选,最后将符合条件的数据按照一定的格式要求显示在网页上

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
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>IFE JavaScript Task 01</title>
</head>
<body>
<h3>污染城市列表</h3>
<ul id="aqi-list">
<!--
<li>第一名:福州(样例),10</li>
<li>第二名:福州(样例),10</li> -->
</ul>
<script type="text/javascript">
var aqiData = [
["北京", 90],
["上海", 50],
["福州", 10],
["广州", 50],
["成都", 90],
["西安", 100]
];
(function () {
/*
在注释下方编写代码
遍历读取aqiData中各个城市的数据
将空气质量指数大于60的城市显示到aqi-list的列表中
*/
})();
</script>
</body>
</html>

注意事项

实现简单功能的同时,请仔细学习JavaScript基本语法、事件、DOM相关的知识

请注意代码风格的整齐、优雅

代码中含有必要的注释

其中的数据以及60的判断逻辑可以自行设定

建议不使用任何第三方库、框架

示例代码仅为示例,可以直接使用,也可以完全自己重写

参考资料

JavaScript入门篇

MDN JavaScript

任务代码

方案一

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>
<head>
<meta charset="utf-8">
<title>IFE JavaScript Task 01</title>
</head>
<body>
<h3>污染城市列表</h3>
<ul id="aqi-list">
</ul>
<script type="text/javascript">
var aqiData = [
["北京", 90],
["上海", 50],
["福州", 10],
["广州", 50],
["成都", 90],
["西安", 100]
];
(function () {
/*
在注释下方编写代码
遍历读取aqiData中各个城市的数据
将空气质量指数大于60的城市显示到aqi-list的列表中
*/
var $ = function(id){
return document.getElementById(id)
}
aqiData.sort(function(a,b){
return b[1]-a[1];
});
var html = '';
var cnum = ['一', '二', '三', '四', '五', '六', '七', '八', '九','十'];
for (var i = 0; i < aqiData.length; i++) {
if (aqiData[i][1] > 60) {
html += '<li>第'+cnum[i]+'名: '+aqiData[i][0]+', '+aqiData[i][1]+'</li>';
}
}
$('aqi-list').innerHTML = html;
})();
</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
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>IFE JavaScript Task 01</title>
</head>
<body>
<h3>污染城市列表</h3>
<ul id="aqi-list">
</ul>
<script type="text/javascript">
var aqiData = [
["北京", 90],
["上海", 50],
["福州", 10],
["广州", 50],
["成都", 90],
["西安", 100]
];
(function () {
/*
在注释下方编写代码
遍历读取aqiData中各个城市的数据
将空气质量指数大于60的城市显示到aqi-list的列表中
*/
var $ = function(id){
return document.getElementById(id)
}
var html = '';
var cnum = ['一', '二', '三', '四', '五', '六', '七', '八', '九','十'];
aqiData.filter(function(element){return element[1] > 60})
.sort(function (d1,d2){ return d2[1] - d1[1]})
.forEach(function(element,index){
html += '<li>第'+cnum[index]+'名: '+element[0]+', '+element[1]+'</li>';
})
$('aqi-list').innerHTML = html;
})();
</script>
</body>
</html>

任务三

任务目的

在上一任务基础上继续JavaScript的体验

接触一下JavaScript中的高级选择器

学习JavaScript中的数组对象遍历、读写、排序等操作

学习简单的字符串处理操作

任务描述

参考以下示例代码,读取页面上已有的source列表,从中提取出城市以及对应的空气质量

将数据按照某种顺序排序后,在resort列表中按照顺序显示出来

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
<!DOCTYPE>
<html>
<head>
<meta charset="utf-8">
<title>IFE JavaScript Task 01</title>
</head>
<body>
<ul id="source">
<li>北京空气质量:<b>90</b></li>
<li>上海空气质量:<b>70</b></li>
<li>天津空气质量:<b>80</b></li>
<li>广州空气质量:<b>50</b></li>
<li>深圳空气质量:<b>40</b></li>
<li>福州空气质量:<b>32</b></li>
<li>成都空气质量:<b>90</b></li>
</ul>
<ul id="resort">
<!--
<li>第一名:北京空气质量:<b>90</b></li>
<li>第二名:北京空气质量:<b>90</b></li>
<li>第三名:北京空气质量:<b>90</b></li>
-->
</ul>
<button id="sort-btn">排序</button>
<script type="text/javascript">
/**
* getData方法
* 读取id为source的列表,获取其中城市名字及城市对应的空气质量
* 返回一个数组,格式见函数中示例
*/
function getData() {
/*
coding here
*/
/*
data = [
["北京", 90],
["北京", 90]
……
]
*/
return data;
}
/**
* sortAqiData
* 按空气质量对data进行从小到大的排序
* 返回一个排序后的数组
*/
function sortAqiData(data) {
}
/**
* render
* 将排好序的城市及空气质量指数,输出显示到id位resort的列表中
* 格式见ul中的注释的部分
*/
function render(data) {
}
function btnHandle() {
var aqiData = getData();
aqiData = sortAqiData(aqiData);
render(aqiData);
}
function init() {
// 在这下面给sort-btn绑定一个点击事件,点击时触发btnHandle函数
}
init();
</script>
</body>
</html>

注意事项

实现简单功能的同时,请仔细学习JavaScript基本语法、事件、DOM相关的知识

请注意代码风格的整齐、优雅

代码中含有必要的注释

建议不使用任何第三方库、框架

示例代码仅为示例,可以直接使用,也可以完全自己重写

参考资料

JavaScript入门篇

MDN JavaScript

任务代码

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
97
98
99
100
101
102
103
104
105
<!DOCTYPE>
<html>
<head>
<meta charset="utf-8">
<title>IFE JavaScript Task 01</title>
</head>
<body>
<ul id="source">
<li>北京空气质量:<b>90</b></li>
<li>上海空气质量:<b>70</b></li>
<li>天津空气质量:<b>80</b></li>
<li>广州空气质量:<b>50</b></li>
<li>深圳空气质量:<b>40</b></li>
<li>福州空气质量:<b>32</b></li>
<li>成都空气质量:<b>90</b></li>
</ul>
<ul id="resort">
<!-- <li>第一名:北京空气质量:<b>90</b></li>
<li>第二名:北京空气质量:<b>90</b></li>
<li>第三名:北京空气质量:<b>90</b></li> -->
</ul>
<button id="sort-btn">排序</button>
<script type="text/javascript">
/**
* getData方法
* 读取id为source的列表,获取其中城市名字及城市对应的空气质量
* 返回一个数组,格式见函数中示例
*/
var $ = function (id){
return document.getElementById(id)
}
function getData() {
/*
coding here
*/
/*
data = [
["北京", 90],
["北京", 90]
……
]
*/
var data = [];
for(var i = 0; i < $('source').children.length; i++){
var str = $('source').children[i].innerText
arr = str.split(':')
data.push(arr)
}
return data;
}
/**
* sortAqiData
* 按空气质量对data进行从小到大的排序
* 返回一个排序后的数组
*/
function sortAqiData(data) {
data.sort(function(a,b){
return b[1]-a[1]
})
return data
}
/**
* render
* 将排好序的城市及空气质量指数,输出显示到id位resort的列表中
* 格式见ul中的注释的部分
*/
function render(data) {
var cnum = ['一', '二', '三', '四', '五', '六', '七', '八', '九','十'];
var html = ''
data.forEach(function(element,index){
html += '<li>第'+cnum[index]+'名: '+element[0]+', <b>'+element[1]+'</b></li>';
})
$('resort').innerHTML = html;
}
function btnHandle() {
var aqiData = getData();
aqiData = sortAqiData(aqiData);
render(aqiData);
$('sort-btn').disabled = true;
}
function init() {
// 在这下面给sort-btn绑定一个点击事件,点击时触发btnHandle函数
$('sort-btn').onclick = btnHandle
}
init();
</script>
</body>
</html>

任务四

任务目的

在上一任务基础上继续JavaScript的体验

深入学习JavaScript的事件机制及DOM操作

学习事件代理机制

学习简单的表单验证功能

学习外部加载JavaScript文件

任务描述

参考以下示例代码,用户输入城市名称和空气质量指数后,点击“确认添加”按钮后,就会将用户的输入在进行验证后,添加到下面的表格中,新增一行进行显示

用户输入的城市名必须为中英文字符,空气质量指数必须为整数

用户输入的城市名字和空气质量指数需要进行前后去空格及空字符处理(trim)

用户输入不合规格时,需要给出提示(允许用alert,也可以自行定义提示方式)

用户可以点击表格列中的“删除”按钮,删掉那一行的数据

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
// task.html
<!DOCTYPE>
<html>
<head>
<meta charset="utf-8">
<title>IFE JavaScript Task 01</title>
<script src="task.js"></script>
</head>
<body>
<div>
<label>城市名称:<input id="aqi-city-input" type="text"></label><br>
<label>空气质量指数:<input id="aqi-value-input" type="text"></label><br>
<button id="add-btn">确认添加</button>
</div>
<table id="aqi-table">
<!--
<tr>
<td>城市</td><td>空气质量</td><td>操作</td>
</tr>
<tr>
<td>北京</td><td>90</td><td><button>删除</button></td>
</tr>
<tr>
<td>北京</td><td>90</td><td><button>删除</button></td>
</tr>
-->
</table>
</body>
</html>
// task.js
/**
* aqiData,存储用户输入的空气指数数据
* 示例格式:
* aqiData = {
* "北京": 90,
* "上海": 40
* };
*/
var aqiData = {};
/**
* 从用户输入中获取数据,向aqiData中增加一条数据
* 然后渲染aqi-list列表,增加新增的数据
*/
function addAqiData() {
}
/**
* 渲染aqi-table表格
*/
function renderAqiList() {
}
/**
* 点击add-btn时的处理逻辑
* 获取用户输入,更新数据,并进行页面呈现的更新
*/
function addBtnHandle() {
addAqiData();
renderAqiList();
}
/**
* 点击各个删除按钮的时候的处理逻辑
* 获取哪个城市数据被删,删除数据,更新表格显示
*/
function delBtnHandle() {
// do sth.
renderAqiList();
}
function init() {
// 在这下面给add-btn绑定一个点击事件,点击时触发addBtnHandle函数
// 想办法给aqi-table中的所有删除按钮绑定事件,触发delBtnHandle函数
}
init();

注意事项

实现简单功能的同时,请仔细学习JavaScript基本语法、事件、DOM相关的知识

请注意代码风格的整齐、优雅

代码中含有必要的注释

验证输入逻辑可以在失去焦点时判断,也可以在点击按钮时判断

建议不使用任何第三方库、框架

示例代码仅为示例,可以直接使用,也可以完全自己重写

参考资料

JavaScript入门篇

MDN JavaScript

任务代码

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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
// task.html
<!DOCTYPE>
<html>
<head>
<meta charset="utf-8">
<title>IFE JavaScript Task 01</title>
<style>
*{
margin: 5px;
}
table{
border-collapse: collapse;
}
table,
tr,
th,
td{
border: 2px solid purple;
}
th,
td{
width: 100px;
height: 30px;
text-align: center;
}
</style>
</head>
<body>
<div>
<label>城市名称:<input id="aqi-city-input" type="text"></label><br>
<label>空气质量指数:<input id="aqi-value-input" type="text"></label><br>
<button id="add-btn">确认添加</button>
</div>
<table id="aqi-table">
<!--
<tr>
<td>城市</td><td>空气质量</td><td>操作</td>
</tr>
<tr>
<td>北京</td><td>90</td><td><button>删除</button></td>
</tr>
<tr>
<td>北京</td><td>90</td><td><button>删除</button></td>
</tr>
-->
</table>
<script src="task.js"></script>
</body>
</html>
// task.js
/**
* aqiData,存储用户输入的空气指数数据
* 示例格式:
* aqiData = {
* "北京": 90,
* "上海": 40
* };
*/
var aqiData = {};
var $ = function (id){
return document.getElementById(id)
}
/**
* 从用户输入中获取数据,向aqiData中增加一条数据
* 然后渲染aqi-list列表,增加新增的数据
*/
function addAqiData() {
var strCity = document.getElementById("aqi-city-input").value.trim();
var strAqi = document.getElementById("aqi-value-input").value.trim();
if (!strCity.match(/^[A-Za-z\u4E00-\u9FA5]+$/)) {
alert("城市名必须为中英文字符!")
return
}else if (!strAqi.match(/^\d+$/)) {
alert("空气质量指数必须为整数!")
return
}
aqiData[strCity] = strAqi;
}
/**
* 渲染aqi-table表格
*/
function renderAqiList() {
var table = document.getElementById("aqi-table");
table.innerHTML = "";
for (var strCity in aqiData) {
if (table.children.length === 0) {
table.innerHTML = "<tr> <td>城市</td> <td>空气质量</td> <td>操作</td> </tr>";
}
var tr = document.createElement("tr");
var td1 = document.createElement("td");
td1.innerHTML = strCity;
tr.appendChild(td1);
var td2 = document.createElement("td");
td2.innerHTML = aqiData[strCity];
tr.appendChild(td2);
var td3 = document.createElement("td");
td3.innerHTML = "<button class='del-btn'>删除</button>";
tr.appendChild(td3);
table.appendChild(tr);
}
}
/**
* 点击add-btn时的处理逻辑
* 获取用户输入,更新数据,并进行页面呈现的更新
*/
function addBtnHandle() {
addAqiData()
renderAqiList()
}
/**
* 点击各个删除按钮的时候的处理逻辑
* 获取哪个城市数据被删,删除数据,更新表格显示
*/
function delBtnHandle(target) {
var tr = target.parentElement.parentElement
var strCity = tr.children[0].innerHTML
delete aqiData[strCity]
// do sth.
renderAqiList()
}
function init() {
// 在这下面给add-btn绑定一个点击事件,点击时触发addBtnHandle函数
$('add-btn').onclick = addBtnHandle
// 想办法给aqi-table中的所有删除按钮绑定事件,触发delBtnHandle函数
$('aqi-table').addEventListener('click',function(e){
if (e.target && e.target.nodeName === "BUTTON") {
delBtnHandle(e.target)
}
})
}
init()

任务五

任务目的

在上一任务基础上继续JavaScript的体验

接触更加复杂的表单对象

实现页面上的一个完整交互功能

用DOM实现一个柱状图图表

任务描述

参考以下示例代码,原始数据包含几个城市的空气质量指数数据

用户可以选择查看不同的时间粒度,以选择要查看的空气质量指数是以天为粒度还是以周或月为粒度

天:显示每天的空气质量指数

周:以自然周(周一到周日)为粒度,统计一周7天的平均数为这一周的空气质量数值,如果数据中缺少一个自然周的几天,则按剩余天进行计算

月:以自然月为粒度,统一一个月所有天的平均数为这一个月的空气质量数值

用户可以通过select切换城市

通过在”aqi-chart-wrap”里添加DOM,来模拟一个柱状图图表,横轴是时间,纵轴是空气质量指数,参考图(点击打开)。天、周、月的数据只根据用户的选择显示一种

天:每天的数据是一个很细的矩形

周:每周的数据是一个矩形

月:每周的数据是一个很粗的矩形

鼠标移动到柱状图的某个柱子时,用title属性提示这个柱子的具体日期和数据

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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
// task.html
<!DOCTYPE>
<html>
<head>
<meta charset="utf-8">
<title>IFE JavaScript Task 01</title>
<script src="task.js"></script>
</head>
<body>
<fieldset id="form-gra-time">
<legend>请选择日期粒度:</legend>
<label>日<input name="gra-time" value="day" type="radio" checked="checked"></label>
<label>周<input name="gra-time" value="week" type="radio"></label>
<label>月<input name="gra-time" value="month" type="radio"></label>
</fieldset>
<fieldset>
<legend>请选择查看的城市:</legend>
<select id="city-select">
<option>北京</option>
</select>
</fieldset>
<div class="aqi-chart-wrap">
</div>
</body>
</html>
// task.js
/* 数据格式演示
var aqiSourceData = {
"北京": {
"2016-01-01": 10,
"2016-01-02": 10,
"2016-01-03": 10,
"2016-01-04": 10
}
};
*/
// 以下两个函数用于随机模拟生成测试数据
function getDateStr(dat) {
var y = dat.getFullYear();
var m = dat.getMonth() + 1;
m = m < 10 ? '0' + m : m;
var d = dat.getDate();
d = d < 10 ? '0' + d : d;
return y + '-' + m + '-' + d;
}
function randomBuildData(seed) {
var returnData = {};
var dat = new Date("2016-01-01");
var datStr = ''
for (var i = 1; i < 92; i++) {
datStr = getDateStr(dat);
returnData[datStr] = Math.ceil(Math.random() * seed);
dat.setDate(dat.getDate() + 1);
}
return returnData;
}
var aqiSourceData = {
"北京": randomBuildData(500),
"上海": randomBuildData(300),
"广州": randomBuildData(200),
"深圳": randomBuildData(100),
"成都": randomBuildData(300),
"西安": randomBuildData(500),
"福州": randomBuildData(100),
"厦门": randomBuildData(100),
"沈阳": randomBuildData(500)
};
// 用于渲染图表的数据
var chartData = {};
// 记录当前页面的表单选项
var pageState = {
nowSelectCity: -1,
nowGraTime: "day"
}
/**
* 渲染图表
*/
function renderChart() {
}
/**
* 日、周、月的radio事件点击时的处理函数
*/
function graTimeChange() {
// 确定是否选项发生了变化
// 设置对应数据
// 调用图表渲染函数
}
/**
* select发生变化时的处理函数
*/
function citySelectChange() {
// 确定是否选项发生了变化
// 设置对应数据
// 调用图表渲染函数
}
/**
* 初始化日、周、月的radio事件,当点击时,调用函数graTimeChange
*/
function initGraTimeForm() {
}
/**
* 初始化城市Select下拉选择框中的选项
*/
function initCitySelector() {
// 读取aqiSourceData中的城市,然后设置id为city-select的下拉列表中的选项
// 给select设置事件,当选项发生变化时调用函数citySelectChange
}
/**
* 初始化图表需要的数据格式
*/
function initAqiChartData() {
// 将原始的源数据处理成图表需要的数据格式
// 处理好的数据存到 chartData 中
}
/**
* 初始化函数
*/
function init() {
initGraTimeForm()
initCitySelector();
initAqiChartData();
}
init();

注意事项

实现简单功能的同时,请仔细学习JavaScript基本语法、事件、DOM相关的知识

请注意代码风格的整齐、优雅

代码中含有必要的注释

示例图仅为参考,不需要完全一致

点击select或者radio选项时,如果没有发生变化,则图表不需要重新渲染

建议不使用任何第三方库、框架

示例代码仅为示例,可以直接使用,也可以完全自己重写

参考资料

JavaScript入门篇

MDN JavaScript

任务代码

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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
// task.html
<!DOCTYPE>
<html>
<head>
<meta charset="utf-8">
<title>IFE JavaScript Task 17</title>
<style>
.aqi-chart-wrap {
display: flex;
width: 90%;
height: 600px;
justify-content: center;
align-items: flex-end;
align-content: center;
margin: 10px auto;
padding: 10px;
border: 2px solid #000;
}
.aqi-chart-wrap div {
border: 1px solid #000;
flex: 1;
}
</style>
</head>
<body>
<fieldset id="form-gra-time">
<legend>请选择日期粒度:</legend>
<label>日<input name="gra-time" value="day" type="radio" checked="checked"></label>
<label>周<input name="gra-time" value="week" type="radio"></label>
<label>月<input name="gra-time" value="month" type="radio"></label>
</fieldset>
<fieldset>
<legend>请选择查看的城市:</legend>
<select id="city-select">
<option>北京</option>
</select>
</fieldset>
<div class="aqi-chart-wrap">
</div>
<script src="task_17.js"></script>
</body>
</html>
// task.js
/* 数据格式演示
var aqiSourceData = {
"北京": {
"2016-01-01": 10,
"2016-01-02": 10,
"2016-01-03": 10,
"2016-01-04": 10
}
};
*/
//跨浏览器事件绑定
function addEventHandler(ele, event, hanlder) {
if (ele.addEventListener) {
ele.addEventListener(event, hanlder, false);
} else if (ele.attachEvent) {
ele.attachEvent("on"+event, hanlder);
} else {
ele["on" + event] = hanlder;
}
}
// 以下两个函数用于随机模拟生成测试数据
function getDateStr(dat) {
var y = dat.getFullYear();
var m = dat.getMonth() + 1;
m = m < 10 ? '0' + m : m;
var d = dat.getDate();
d = d < 10 ? '0' + d : d;
return y + '-' + m + '-' + d;
}
function randomBuildData(seed) {
var returnData = {};
var dat = new Date("2016-01-01");
var datStr = ''
for (var i = 1; i < 92; i++) {
datStr = getDateStr(dat);
returnData[datStr] = Math.ceil(Math.random() * seed);
dat.setDate(dat.getDate() + 1);
}
return returnData;
}
var aqiSourceData = {
"北京": randomBuildData(500),
"上海": randomBuildData(300),
"广州": randomBuildData(200),
"深圳": randomBuildData(100),
"成都": randomBuildData(300),
"西安": randomBuildData(500),
"福州": randomBuildData(100),
"厦门": randomBuildData(100),
"沈阳": randomBuildData(500)
};
// 用于渲染图表的数据
var chartData = {};
// 记录当前页面的表单选项
var pageState = {
nowSelectCity: "北京",
nowGraTime: "day"
}
var formGraTime = document.getElementById('form-gra-time');
var citySelect = document.getElementById('city-select');
var aqiChartWrap = document.getElementsByClassName('aqi-chart-wrap')[0];
/**
* 渲染图表
*/
function renderChart() {
var color = '',text = '';
for (var item in chartData) {
color = '#' + Math.floor(Math.random() * 0xFFFFFF).toString(16);
text += '<div title="'+item+":"+chartData[item]+'" style="height:'+chartData[item]+'px; background-color:'+color+'"></div>';
}
aqiChartWrap.innerHTML = text;
}
/**
* 日、周、月的radio事件点击时的处理函数
*/
function graTimeChange() {
// 确定是否选项发生了变化
if (pageState.nowGraTime == this.value) {
return;
} else {
pageState.nowGraTime = this.value;
}
// 设置对应数据
initAqiChartData();
// 调用图表渲染函数
renderChart();
}
/**
* select发生变化时的处理函数
*/
function citySelectChange() {
// 确定是否选项发生了变化
if (pageState.nowSelectCity == this.value) {
return;
} else {
pageState.nowSelectCity = this.value;
}
// 设置对应数据
initAqiChartData();
// 调用图表渲染函数
renderChart();
}
/**
* 初始化日、周、月的radio事件,当点击时,调用函数graTimeChange
*/
function initGraTimeForm() {
var pageRadio = formGraTime.getElementsByTagName('input');
for (var i = 0; i < pageRadio.length; i++) {
addEventHandler(pageRadio[i],'click',graTimeChange);
}
}
/**
* 初始化城市Select下拉选择框中的选项
*/
function initCitySelector() {
// 读取aqiSourceData中的城市,然后设置id为city-select的下拉列表中的选项
var cityList = '';
for (var i in aqiSourceData) {
cityList += '<option>' + i +'</option>';
}
citySelect.innerHTML = cityList;
// 给select设置事件,当选项发生变化时调用函数citySelectChange
addEventHandler(citySelect,'change',citySelectChange)
}
/**
* 初始化图表需要的数据格式
*/
function initAqiChartData() {
// 将原始的源数据处理成图表需要的数据格式,现在数据都在aqiSourceData[]中
// 处理好的数据存到 chartData 中
var nowCityData = aqiSourceData[pageState.nowSelectCity];
//nowCityData是确定的一个城市的92天降水数组,key是日期,nowCityData[key]是降水量
if (pageState.nowGraTime == 'day') {
chartData = nowCityData;
}
if (pageState.nowGraTime == 'week') {
chartData = {};
var countSum=0, daySum=0, week=0;
for (var item in nowCityData) {
countSum += nowCityData[item];
daySum ++;
if ((new Date(item)).getDay() == 6 ) {
week ++;
chartData['第'+week+'周'] = Math.floor(countSum/daySum);;
countSum = 0;
daySum = 0;
}
}
if (daySum!=0) {
week ++;
chartData['第'+week+'周'] = Math.floor(countSum/daySum);
}//保证最后一周若不满也能算一周
}
if (pageState.nowGraTime == 'month') {
chartData = {};
var countSum=0, daySum=0, month=0;
for (var item in nowCityData) {
countSum += nowCityData[item];
daySum ++;
if ((new Date(item)).getMonth() !== month) {
month ++;
chartData['第'+month+'月'] = Math.floor(countSum/daySum);
countSum = 0
daySum = 0;
}
}
if (daySum != 0) {
month ++;
chartData['第'+month+'月'] = Math.floor(countSum/daySum);
}//逻辑同周,不知道对不对
}
}
/**
* 初始化函数
*/
function init() {
initGraTimeForm()
initCitySelector();
initAqiChartData();
renderChart();
}
init();