ZhangYang's Blog

【实战】IFE的JavaScript练习

任务一

任务目的

学习与实践JavaScript的基本语法、语言特性

初步了解JavaScript的事件是什么

初步了解JavaScript中的DOM是什么

任务描述

如图,模拟一个队列,队列的每个元素是一个数字,初始队列为空

有一个input输入框,以及4个操作按钮

点击”左侧入”,将input中输入的数字从左侧插入队列中;

点击”右侧入”,将input中输入的数字从右侧插入队列中;

点击”左侧出”,读取并删除队列左侧第一个元素,并弹窗显示元素中数值;

点击”右侧出”,读取并删除队列又侧第一个元素,并弹窗显示元素中数值;

点击队列中任何一个元素,则该元素会被从队列中删除

注意事项

实现简单功能的同时,请仔细学习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
144
145
146
147
148
149
150
151
152
153
154
// task.html
<!DOCTYPE>
<html>
<head>
<meta charset="utf-8">
<title>IFE JavaScript Task 02</title>
<style>
#leftIn,
#rightIn,
#leftOut,
#rightOut {
margin:2px 4px;
border: 1px solid #ddd;
background: white;
}
#rightIn {
margin-right: 20px;
}
.numContent{
height: 40px;
}
span{
height: 30px;
display: inline-block;
text-align: center;
color: white;
background-color: red;
padding: 0 10px;
padding-top: 10px;
margin-right: 10px;
}
</style>
</head>
<body>
<input type="text" id="num">
<button id="leftIn">左侧入</button><button id="rightIn">右侧入</button>
<button id="leftOut">左侧出</button><button id="rightOut">右侧出</button>
<div id="numContent">
</div>
<script>
//事件绑定函数,兼容浏览器差异
function addEvent(element, event, listener) {
if (element.addEventListener) {
element.addEventListener(event, listener, false);
}
else if (element.attachEvent) {
element.attachEvent("on" + event, listener);
}
else {
element["on" + event] = listener;
}
}
// 复用id选择器
function $(id){
return document.getElementById(id);
}
//遍历数组的方法,针对数组中每一个元素执行fn函数,并将数组索引和元素作为参数传递
function each(arr, fn) {
for (var cur = 0; cur < arr.length; cur++) {
fn(arr[cur]);
}
}
var queue = {
str: [],
paint: function(){
var html = '';
each(this.str,function(item){
html += "<span>"+parseInt(item)+"</span>"
})
$('numContent').innerHTML = html;
addDivDelEvent();
},
leftPush: function(num){
this.str.unshift(num)
this.paint();
},
rightPush: function(num) {
this.str.push(num);
this.paint();
},
isEmpty: function(){
return this.str.length == 0;
},
leftPop: function() {
if (!this.isEmpty()) {
alert(this.str.shift());
this.paint();
}
else {
alert("队列已经是空的!");
}
},
rightPop: function() {
if (!this.isEmpty()) {
alert(this.str.pop());
this.paint();
}
else {
alert("队列已经是空的!");
}
},
deleteID: function(id) {
this.str.splice(id, 1);
this.paint();
}
}
// 为numContent中的每个span绑定删除函数
function addDivDelEvent() {
for (var cur = 0; cur < $('numContent').childNodes.length; cur++) {
// 这里要使用闭包,否则永远绑定到指定span上的delete函数的cur永远等于跳出循环时的cur值(length)
addEvent($('numContent').childNodes[cur], "click", function(cur) {
return function(){
return queue.deleteID(cur)
}
}(cur))
}
}
// 4个按钮分别绑定事件函数
addEvent($("leftIn"),'click',function(){
var num = $('num').value;
if((/^[0-9]+$/).test(num)){
queue.leftPush(num)
}else{
alert("请输入一个整数!")
}
})
addEvent($("rightIn"),'click',function(){
var num = $('num').value;
if((/^[0-9]+$/).test(num)){
queue.rightPush(num)
}else{
alert("请输入一个整数!")
}
})
addEvent($("leftOut"),'click',function(){
queue.leftPop()
})
addEvent($("rightOut"),'click',function(){
queue.rightPop()
})
</script>
</body>
</html>

预览

任务一

任务二

任务目的

学习与实践JavaScript的基本语法、语言特性

练习使用JavaScript实现简单的排序算法

任务描述

基于任务18

限制输入的数字在10-100

队列元素数量最多限制为60个,当超过60个时,添加元素时alert出提示

队列展现方式变化如图,直接用高度表示数字大小

实现一个简单的排序功能,如冒泡排序(不限制具体算法),用可视化的方法表达出来,参考见下方参考资料

注意事项

实现简单功能的同时,请仔细学习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
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
<!DOCTYPE>
<html>
<head>
<meta charset="utf-8">
<title>IFE JavaScript Task 02</title>
<style>
button {
margin:2px 4px;
border: 1px solid #ddd;
background: white;
}
#numContent {
display: flex;
width: 500px;
height: 150px;
align-items: flex-end;
}
#numContent span {
padding: 0 15px;
margin-right: 10px;
background-color: red;
}
</style>
</head>
<body>
<input type="text" id="num">
<button id="leftIn">左侧入</button><button id="rightIn">右侧入</button>
<button id="leftOut">左侧出</button><button id="rightOut">右侧出</button>
<button id="sortBtn">队列排序</button>
<div id="numContent">
</div>
<script>
//事件绑定函数,兼容浏览器差异
function addEvent(element, event, listener) {
if (element.addEventListener) {
element.addEventListener(event, listener, false);
}
else if (element.attachEvent) {
element.attachEvent("on" + event, listener);
}
else {
element["on" + event] = listener;
}
}
// 复用id选择器
function $(id){
return document.getElementById(id);
}
//遍历数组的方法,针对数组中每一个元素执行fn函数,并将数组索引和元素作为参数传递
function each(arr, fn) {
for (var cur = 0; cur < arr.length; cur++) {
fn(arr[cur]);
}
}
var queue = {
str: [],
paint: function(){
var html = '';
each(this.str,function(item){
html += "<span style='height:"+parseInt(item)+"'></span>"
})
$('numContent').innerHTML = html;
addDivDelEvent();
},
leftPush: function(num){
if (this.str.length >= 60) {
alert("队列元素数量最多为60个!");
}else{
this.str.unshift(num);
this.paint();
}
},
rightPush: function(num) {
if (this.str.length >= 60) {
alert("队列元素数量最多为60个!");
}else{
this.str.push(num);
this.paint();
}
},
isEmpty: function(){
return this.str.length == 0;
},
leftPop: function() {
if (!this.isEmpty()) {
alert(this.str.shift());
this.paint();
}
else {
alert("队列已经是空的!");
}
},
rightPop: function() {
if (!this.isEmpty()) {
alert(this.str.pop());
this.paint();
}
else {
alert("队列已经是空的!");
}
},
deleteID: function(id) {
this.str.splice(id, 1);
this.paint();
},
// 冒泡排序
sortElements:function(){
var Clock;
var count = 0, i = 0;
Clock = setInterval(function() {
if (count >= this.str.length) {
clearInterval(Clock);
}
if (i == this.str.length - 1 - count) {
i = 0;
count++;
}
if (this.str[i] > this.str[i + 1]) {
var temp = this.str[i];
this.str[i] = this.str[i + 1];
this.str[i + 1] = temp;
this.paint();
}
i++;
}.bind(this), 100);
}
}
// 为numContent中的每个span绑定删除函数
function addDivDelEvent() {
for (var cur = 0; cur < $('numContent').childNodes.length; cur++) {
// 使用立即执行函数,来解决闭包的影响
addEvent($('numContent').childNodes[cur], "click", function(cur) {
return function(){
return queue.deleteID(cur)
}
}(cur))
}
}
// 4个按钮分别绑定事件函数
addEvent($("leftIn"),'click',function(){
var num = $('num').value;
if((/^[0-9]+$/).test(num)){
// 限制输入的数字在10-100
if (parseInt(num) < 10 || parseInt(num) > 100) {
alert("输入的数字必须在10-100之间!")
}else{
queue.leftPush(num)
}
}else{
alert("请输入一个整数!")
}
})
addEvent($("rightIn"),'click',function(){
var num = $('num').value;
if((/^[0-9]+$/).test(num)){
// 限制输入的数字在10-100
if (parseInt(num) < 10 || parseInt(num) > 100) {
alert("输入的数字必须在10-100之间!")
}else{
queue.rightPush(num)
}
}else{
alert("请输入一个整数!")
}
})
addEvent($("leftOut"),'click',function(){
queue.leftPop()
})
addEvent($("rightOut"),'click',function(){
queue.rightPop()
})
addEvent($("sortBtn"),'click',function(){
queue.sortElements()
})
</script>
</body>
</html>

预览

任务二

任务三

任务目的

实践JavaScript数组、字符串相关操作

任务描述

基于任务18进行升级

将新元素输入框从input改为textarea

允许一次批量输入多个内容,格式可以为数字、中文、英文等,可以通过用回车,逗号(全角半角均可),顿号,空格(全角半角、Tab等均可)等符号作为不同内容的间隔

增加一个查询文本输入框,和一个查询按钮,当点击查询时,将查询词在各个元素内容中做模糊匹配,将匹配到的内容进行特殊标识,如文字颜色等。举例,内容中有abcd,查询词为ab或bc,则该内容需要标识

注意事项

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

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

代码中含有必要的注释

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

参考资料

JavaScript入门篇

MDN JavaScript

归并排序算法可视化

15种排序算法可视化展示

任务代码

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
<!DOCTYPE>
<html>
<head>
<meta charset="utf-8">
<title>IFE JavaScript Task 02</title>
<style>
button {
margin:2px 4px;
border: 1px solid #ddd;
background: white;
}
.numContent{
height: 40px;
}
span{
height: 30px;
display: inline-block;
text-align: center;
color: white;
background-color: red;
padding: 0 10px;
padding-top: 10px;
margin-right: 10px;
}
</style>
</head>
<body>
<textarea id="num" cols="40" rows="10">你好,大家好, 才是 真的哈哈、好啊</textarea>
<button id="leftIn">左侧入</button><button id="rightIn">右侧入</button>
<button id="leftOut">左侧出</button><button id="rightOut">右侧出</button>
<input type="text" id="searchInput">
<button id="searchBtn">查询</button>
<div id="numContent">
</div>
<script>
//事件绑定函数,兼容浏览器差异
function addEvent(element, event, listener) {
if (element.addEventListener) {
element.addEventListener(event, listener, false);
}
else if (element.attachEvent) {
element.attachEvent("on" + event, listener);
}
else {
element["on" + event] = listener;
}
}
// 复用id选择器
function $(id){
return document.getElementById(id);
}
//遍历数组的方法,针对数组中每一个元素执行fn函数,并将数组索引和元素作为参数传递
function each(arr, fn) {
for (var cur = 0; cur < arr.length; cur++) {
fn(arr[cur]);
}
}
// 为numContent中的每个span绑定删除函数
function addDivDelEvent() {
for (var cur = 0; cur < $('numContent').childNodes.length; cur++) {
// 这里要使用闭包,否则永远绑定到指定span上的delete函数的cur永远等于跳出循环时的cur值(length)
addEvent($('numContent').childNodes[cur], "click", function(cur) {
return function(){
return queue.deleteID(cur)
}
}(cur))
}
}
// 将输入的内容分割为数组
function spiltInput(text) {
var inputArray = [];
inputArray = (text).split(/[,,;;、\s\n]+/);
return inputArray;
}
var queue = {
str: [],
paint: function(){
var html = '';
each(this.str,function(item){
html += "<span>"+item+"</span>"
})
$('numContent').innerHTML = html;
addDivDelEvent();
},
leftPush: function(num){
for(var cur in num){
this.str.unshift(num[cur]);
}
this.paint();
},
rightPush: function(num) {
for(var cur in num){
this.str.push(num[cur]);
}
this.paint();
},
isEmpty: function(){
return this.str.length == 0;
},
leftPop: function() {
if (!this.isEmpty()) {
alert(this.str.shift());
this.paint();
}
else {
alert("队列已经是空的!");
}
},
rightPop: function() {
if (!this.isEmpty()) {
alert(this.str.pop());
this.paint();
}
else {
alert("队列已经是空的!");
}
},
deleteID: function(id) {
this.str.splice(id, 1);
this.paint();
},
searchNumContent: function(num){
for (var i = 0; i < $('numContent').childNodes.length; i++) {
$('numContent').childNodes[i].style.color = "#FFFFFF";
$('numContent').childNodes[i].style.background = "red";
if ($('numContent').childNodes[i].innerHTML.indexOf(num) != -1) {
$('numContent').childNodes[i].style.color = "green";
$('numContent').childNodes[i].style.background = "black";
}
}
}
}
// 4个按钮分别绑定事件函数
addEvent($("leftIn"),'click',function(){
var num = spiltInput($('num').value.trim())
queue.leftPush(num)
})
addEvent($("rightIn"),'click',function(){
var num = spiltInput($('num').value.trim())
queue.rightPush(num)
})
addEvent($("leftOut"),'click',function(){
queue.leftPop()
})
addEvent($("rightOut"),'click',function(){
queue.rightPop()
})
addEvent($("searchBtn"),'click',function(){
var num = $("searchInput").value
queue.searchNumContent(num)
})
</script>
</body>
</html>

预览

任务三

任务四

任务目的

学习与实践JavaScript的基本语法、语言特性

练习使用JavaScript实现拖拽功能

任务描述

基于任务20,将任务20的代码进行抽象、封装,然后在此基础上实现如图中的两个需求:Tag输入和兴趣爱好输入

如示例图上方,实现一个tag输入框

要求遇到用户输入空格,逗号,回车时,都自动把当前输入的内容作为一个tag放在输入框下面

Tag不能有重复的,遇到重复输入的Tag,自动忽视

每个Tag请做trim处理

最多允许10个Tag,多于10个时,按照录入的先后顺序,把最前面的删掉

当鼠标悬停在tag上时,tag前增加删除二字,点击tag可删除

如示例图下方,实现一个兴趣爱好输入的功能

通过一个Textarea进行兴趣爱好的输入,可以通过用回车,逗号(全角半角均可),顿号,空格(全角半角、Tab等均可)等符号作为间隔

当点击“确认兴趣爱好”的按钮时,将textarea中的输入按照你设定的间隔符,拆解成一个个的爱好,显示在textarea下方

爱好不能重复,所以在下方呈现前,需要做一个去重

每个爱好内容需要做trim处理

最多允许10个兴趣爱好,多于10个时,按照录入的先后顺序,把最前面的删掉

注意事项

实现简单功能的同时,请仔细学习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
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
<!DOCTYPE>
<html>
<head>
<meta charset="utf-8">
<title>IFE JavaScript Task 02</title>
<style>
button {
margin:2px 4px;
border: 1px solid #ddd;
background: white;
}
#numContent,
#tagContent{
margin-top: 20px;
}
textarea{
margin-top: 20px;
}
span{
height: 30px;
display: inline-block;
text-align: center;
color: white;
background-color: red;
padding: 0 10px;
padding-top: 10px;
margin-right: 10px;
}
</style>
</head>
<body>
<label>Tag: <input type="text" id="tagInput"></label>
<div id="tagContent">
</div>
<textarea id="num" cols="40" rows="10">你好,大家好, 才是 真的哈哈、好啊</textarea>
<br>
<button id="sureBtn">确认兴趣按钮</button>
<div id="numContent">
</div>
<script>
//事件绑定函数,兼容浏览器差异
function addEvent(element, event, listener) {
if (element.addEventListener) {
element.addEventListener(event, listener, false);
}
else if (element.attachEvent) {
element.attachEvent("on" + event, listener);
}
else {
element["on" + event] = listener;
}
}
// 复用id选择器
function $(id){
return document.getElementById(id);
}
//遍历数组的方法,针对数组中每一个元素执行fn函数,并将数组索引和元素作为参数传递
function each(arr, fn) {
for (var cur = 0; cur < arr.length; cur++) {
fn(arr[cur]);
}
}
// 为numContent中的每个span绑定删除函数
function addDivDelEvent(Queue, container) {
console.log(container.childNodes)
var temp = []
for (var cur = 0; cur < container.childNodes.length; cur++) {
temp.push(container.childNodes[cur].innerHTML);
// 这里要使用闭包,否则永远绑定到指定span上的delete函数的cur永远等于跳出循环时的cur值(length)
addEvent(container.childNodes[cur], "click", function(cur) {
return function(){
return Queue.deleteID(cur)
}
}(cur))
addEvent(container.childNodes[cur], "mouseover", function(cur) {
return function(){
container.childNodes[cur].style.background = "green";
container.childNodes[cur].innerHTML = "删除" + temp[cur] + "?";
}
}(cur))
addEvent(container.childNodes[cur], "mouseout", function(cur) {
return function(){
container.childNodes[cur].style.background = "red";
container.childNodes[cur].innerHTML = temp[cur];
}
}(cur))
}
}
// 将输入的内容分割为数组
function spiltInput(text) {
var inputArray = [];
inputArray = (text).split(/[,,;;、\s\n]+/);
return inputArray;
}
function Queue(container,isDelDiv){
this.str = []
this.paint = function(){
var html = '';
each(this.str,function(item){
html += "<span>"+item+"</span>"
})
container.innerHTML = html;
if(isDelDiv){
addDivDelEvent(this,container)
};
}
this.leftPush = function(obj) {
if (obj.length) {
this.str.unshift(obj);
this.paint();
}
}
this.rightPush = function(obj) {
if (obj.length) {
this.str.push(obj);
this.paint();
}
}
this.isEmpty = function() {
return (this.str.length == 0);
}
this.leftPop = function() {
if (!this.isEmpty()) {
this.str.shift();
this.paint();
}
else {
alert("The queue is already empty!");
}
}
this.rightPop = function() {
if (!this.isEmpty()) {
this.str.pop();
this.paint();
}
else {
alert("The queue is already empty!");
}
}
this.deleteID = function(id) {
this.str.splice(id, 1);
this.paint();
}
}
//实例1:Tag;
var tagQueue = new Queue($('tagContent'), true);
//实例2:不用给div增加删除事件
var queue = new Queue($('numContent'), false);
// 确认按钮分别绑定事件函数
addEvent($("sureBtn"),'click',function(){
var num = spiltInput($('num').value.trim())
each(num, function(item, index) {
if (queue.str.indexOf(item) === -1) {
queue.rightPush(item);
if (queue.str.length > 10) {
queue.leftPop();
}
}
})
})
addEvent($("tagInput"),'keyup',function(e){
if (/[,,;;、\s\n]+/.test($("tagInput").value) || e.keyCode ===13) {
var tagInput = spiltInput($('tagInput').value.trim())
var data = tagInput[0]
if (tagQueue.str.indexOf(data) === -1) {
tagQueue.rightPush(data)
if (tagQueue.str.length > 10) {
tagQueue.leftPop()
}
}
$("tagInput").value = "";
}
})
</script>
</body>
</html>

预览

任务四