1. 简介

JavaScript用于网页和用户之间的交互,比如提交的时候,进行用户名是否为空的判断。

JavaScript代码必须放在script标签中,建议把script标签放在body标签快结束的位置,否则可能影响页面内容的加载。和CSS一样,当JavaScript代码特别多,并且都写在HTML里的时候,会显得比较繁杂,难以维护。这个时候可以采取和CSS一样的手段,单独剥离出来放在.js文件中,在HTML中引用该文件即可。

1
<script src="文件位置" type="text/javascript"></script>

JavaScript中的注释方式和Java相同,//用于单行注释;/**/用于多行注释。

2. 基础知识

2.1 变量

使用var关键字声明一个变量。

注意:不使用var关键字也可以声明变量,当没有使用var时,创建的变量为全局变量!

2.2 调试

在浏览器中的检查-console中查看错误信息

2.3 基本数据类型

  • Number
  • String
  • Boolean
  • undefined 声明了但没有赋值
  • null 空对象/对象不存在

使用typeof来进行判断数据类型。

2.4 数据类型转换

有点类似于java中的装箱拆箱,JavaScript中具有伪对象的概念:即使是基本类型,也是伪对象,都有自己的属性和方法。

2.4.1 转换为字符串

Number Boolean String都有一个toString方法,可以转换为字符串

注意:数字转换为字符串,toString(参数)中参数是数字几表示转换为几进制的字符串(默认是10进制)

例如:

1
2
3
var a = 10;
// 将a转换为二进制的字符串
document.write(a.toString(2))

2.4.2 转换为数字

parseInt() parseFloat()可以转换为数字

2.4.3 转换为布尔类型

Boolean()可以转换为布尔类型,非空为true、非0为true、非null为true

2.5 函数

使用如下格式的代码定义一个函数。

1
2
3
function get() {
document.write("自定义函数");
}

2.6 条件、循环

整体均类似于java,具体有不同的地方用到再进行学习。

3. 练习

3.1 练习01

做一个简单的加法计算器。

在线观看

HTML

1
2
3
4
5
6
7
8
9
10
11
12
13
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link rel="stylesheet" href="style.css" type="text/css">
</head>
<body>
<div class="layout">
<input type="text" id="num1"> + <input type="text" id="num2"> = <input type="text" id="sum">
<input type="button" value="运算" onclick="getSum()">
</div>
<script src="calc.js" type="text/javascript"></script>
</body>
</html>

CSS

1
2
3
4
5
6
7
8
9
10
div.layout {
margin: auto;
width: 400px;
height: 200px;
padding-top: 200px;
}

input {
width: 80px;
}

JavaScript

1
2
3
4
5
6
7
function getSum() {
// 注意这里直接得到的值是字符串类型,要转换成Number类型进行计算
var num1 = document.getElementById("num1").value;
var num2 = document.getElementById("num2").value;
var sum = parseFloat(num1) + parseFloat(num2);
document.getElementById("sum").value = sum;
}

这里使用了DOM的知识获取输入框的值以及将值返回到输入框,后面会详细提到。

3.2 练习02

使用格式化字符串的知识,做出如下功能的界面。

在线观看

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
<html>
<head>
<meta http-equiv="Content-Type"content="text/html; charset=utf-8">
<link rel="stylesheet" href="style.css" type="text/css">
</head>
<body>
<div class="layout">
<span class="tag">地名:</span> <input type="text" id="locate">
<span class="tag">公司类型:</span> <input type="text" id="companyType">
<br>
<span class="tag">公司名称:</span> <input type="text" id="companyName">
<span class="tag">老板姓名:</span> <input type="text" id="bossName">
<br>
<span class="tag">money:</span> <input type="text" id="totalMoney">
<span class="tag">产品:</span> <input type="text" id="product">
<br>
<span class="tag">价格计量单位:</span> <input type="text" id="moneyUnit">
<br>
<center><input type="button" value="生成" class="button" onclick="format()"></center>
<textarea id="result"></textarea>
</div>
<script src="stringFormat.js" type="text/javascript"></script>
</body>
</html>

CSS

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
div.layout {
margin: auto;
width: 700px;
height: 500px;
padding: 200px;
}

body {
font-family: 宋体;
}

span.tag {
border-width: 1px;
border-color: lightgray;
border-style: solid;
width: 100px;
margin-right: 10px;
margin-bottom: 20px;
display: inline-block;
}

input.button {
width: 100px;
height: 30px;
}

textarea {
width: 100%;
height: 200px;
margin-top: 20px;
}

JavaScript

1
2
3
4
5
6
7
8
9
10
11
function format() {
var locate = document.getElementById("locate").value;
var companyType = document.getElementById("companyType").value;
var companyName = document.getElementById("companyName").value;
var bossName = document.getElementById("bossName").value;
var totalMoney = document.getElementById("totalMoney").value;
var product = document.getElementById("product").value;
var moneyUnit = document.getElementById("moneyUnit").value;
var result = locate + "最大" + companyType + companyName + "倒闭了,王八蛋老板" + bossName + "吃喝嫖赌,欠下了" + totalMoney + "个亿,带着他的小姨子跑了!我们没有办法,拿着" + product + "抵工资!原价都是一" + moneyUnit + "多、两" + moneyUnit + "多、三" + moneyUnit + "多的" + product + ",现在全部只卖二十块,统统只要二十块!" + bossName + "王八蛋,你不是人!我们辛辛苦苦给你干了大半年,你不发工资,你还我血汗钱,还我血汗钱!";
document.getElementById("result").value = result;
}

这里当时做的时候遇上了不小的麻烦👀,还是对CSS的掌握不够熟练。一开始看到这个网页样式时,想到的是用table标签的方式去做,但是做出来后元素之间的距离无法调整,达不到目标样式。因为我们可以对表格table设置margin,而不能设置padding;对单元格td可以设置padding,而不能设置margin。所以不能通过对单元格td设置margin来调整元素之间的距离。而这里的目标样式是带边框的,需要通过调整margin来调节距离。去找答案,看到了inline-block这一参数🙄。

  • block:将元素显示为块级元素。特点:总是在新行上开始;高度、行高以及顶和底边距都可以控制。例如<div>, <p>, <li>, <h>都是块元素。
  • inline:将元素显示为行内元素。特点:和其它元素都在一行上;高度、行高以及顶和底边距不能改变;宽度就是其文字或图片的宽度,不可改变。例如<span>, <a>都是行内元素。
  • inline-block:使块对象可以在同一行显示,并且可以调节其高度、行高以及顶和底边距。

inline-block正好满足了我的需求😮~

3.3 练习03

实现计算复利的效果。

在线观看

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
<html>
<head>
<meta http-equiv="Content-Type"content="text/html; charset=utf-8">
<link rel="stylesheet" href="style.css" type="text/css">
</head>
<body>
<div class="layout">
<table>
<tr>
<td>起始资金</td>
<td><input type="text" id="principal"></td>
</tr>
<tr>
<td>每年收益</td>
<td><input type="text" id="profitPerYear"> %</td>
</tr>
<tr>
<td>复利年数</td>
<td><input type="text" id="numberOfYears"></td>
</tr>
<tr>
<td>每年追加资金</td>
<td><input type="text" id="appendMoney"></td>
</tr>
<tr>
<td colspan="2" align="center"><input type="button" value="计算" onclick="calcProfit()"></td>
</tr>
<tr>
<td>本金和</td>
<td><input type="text" value="0" disabled="disabled" id="sum1"></td>
</tr>
<tr>
<td>利息和</td>
<td><input type="text" value="0" disabled="disabled" id="sum2"></td>
</tr>
<tr>
<td>本息和</td>
<td><input type="text" value="0" disabled="disabled" id="sum3"></td>
</tr>
</table>
</div>
<script src="calcProfit.js" type="text/javascript"></script>
</body>
</html>

CSS

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
body {
font-family: 宋体;
}

div.layout {
margin: auto;
width: 400px;
height: 500px;
padding: 100px;
}

table {
border-collapse: collapse;
width: 100%;
}

td {
border-style: solid;
border-width: 1px;
border-color: lightgray;
padding: 5px;
font-size: 20px;
}

input {
width: 180px;
}

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
function getValue(id) {
var value = document.getElementById(id).value;
return parseFloat(value);
}

// 取幂
function getPower(num, power) {
if (0 == power) {
return 1;
}else if (1 == power) {
return num;
}else {
var result = 1;
for (var i = 1; i <= power; i++) {
result = result * num;
}
return result;
}
}

// 求复利
function getCompoundInterest(rate, numberOfYears) {
if (0 == numberOfYears || 1 == numberOfYears) {
return 0;
} else {
var interestRate = 0;
for (var i = numberOfYears-1; i > 0; i--) {
interestRate += getPower(rate, i);
}
return interestRate;
}
}

function calcProfit() {
var principal = getValue("principal");
var profitPerYear = getValue("profitPerYear");
var numberOfYears = getValue("numberOfYears");
var appendMoney = getValue("appendMoney");
var sum1 = principal + appendMoney * (numberOfYears - 1);
var sum3 = principal * getPower((1 + profitPerYear * 0.01), numberOfYears) + appendMoney * getCompoundInterest((1 + profitPerYear * 0.01), numberOfYears);
var sum2 = sum3 - sum1;

document.getElementById("sum1").value = sum1.toFixed(2);
document.getElementById("sum2").value = sum2.toFixed(2);
document.getElementById("sum3").value = sum3.toFixed(2);
}

这里的输入框使用了disabled属性,之前没有用过的,作用是使用户不能在网页上输入框中输入文本,只能显示文本。

4. 对象

JavaScript的对象也比较好理解,类似于java,目前还没有用到,用到的时候再进行查阅学习。

参考How2j的教程😁

5. BOM

BOM即浏览器对象模型(Browser Object Model)

浏览器对象包括:

  • Window(窗口)
  • Navigator(浏览器)
  • Screen(客户端屏幕)
  • History(访问历史)
  • Location(浏览器地址)

通过浏览器对象模型,我们可以获得用户的浏览器对象的相关信息,从而达到项目目的。

5.1 Window

通过window对象获取文档显示区域的高度和宽度

```window.innerWidth

获取外部浏览器的高度和宽度

```window.outerWidth

5.1.1 弹出框

浏览器上常见的弹出框有警告框,确认框,提示框,都是调用window对象实现的。但由于十分常用,所以把window省略掉了。

  • 警告框:常用于提示信息 alert(内容)
  • 确认框:常用于危险性操作的确认提示,返回布尔类型的true或false var boolean = confirm(内容)
  • 输入框:供用户输入相关信息(很少使用) var string = prompt(内容)

5.2 Navigator

通过Navigator对象获取浏览器的相关信息

属性 内容
navigator.appName 浏览器产品名称
navigator.appVersion 浏览器版本号
navigator.appCodeName 浏览器内部代码
navigator.platform 浏览器操作系统
navigator.cookieEnabled 浏览器是否启用Cookies
navigator.userAgent 浏览器的用户代理报头

5.3 Screen

通过Screen对象获取用户屏幕相关信息。

获取用户屏幕分辨率
screen.width screen.height

获取用户屏幕可用区域大小
screen.availWidth screen.availHeight

5.4 History

通过History对象记录访问历史

返回上一次访问


返回上上次的访问
```history.go(-2) // -1表示上次,-2表示上上次,以此类推

5.5 Location

通过Location对象控制网页地址。

刷新当前页面location.reload()

跳转到另一个页面location="/" location.assign("/")

区别:assign会添加记录到浏览历史,点击后退可以返回之前页面

属性 内容
location.protocol 协议
location.hostname 主机号
location.port 端口号
location.host 主机+端口号
location.pathname 访问路径
location.hash 锚点
location.search 参数列表

5.6 计时器

方法 作用
setTimeout(函数, 毫秒数) 毫秒数结束之后执行函数
setInterval(函数, 间隔毫秒数) 重复执行函数
clearInterval(重复执行的任务) 终止一个不断重复地任务

clearInterval例子:

1
2
var task = setInterval(print, 2000);
clearInterval(task); // 终止task

6. DOM

DOM即文档对象模型(Document Object Model)。

DOM是把HTML里面的各种数据当作对象进行操作的一种思路。

DOM把所有的HTML都转换为节点。

  • 元素节点
  • 属性节点
  • 内容节点

6.1 获取节点

  1. 获取元素节点
  • 通过id document.getElementById(id)
  • 通过标签 document.getElementsByTagName(标签)
  • 通过类名 document.getElementsByClassName(类名)
  1. 获取属性节点

先获取对应的元素节点,然后通过元素节点的attributes获取其下所有的属性节点。使用nodeName和nodeValue查看属性名和属性值。

  1. 获取内容节点

先获取对应的元素节点,然后用过childNodes获取其所有的子节点,其中第一个子节点就是内容节点。使用nodeName和nodeValue查看内容节点名和内容节点值。

innerHTML表示元素的文本内容

6.2 事件

鼠标、键盘等在网页上的一系列动作称为事件,通过捕获事件执行对应的函数来实现网页的交互。

事件 关键字
焦点事件(文本框) onfocus onblur
鼠标事件 onmousedown onmouseup onmousemove onmouseout
键盘事件 onkeydown onkeypress onkeyup
点击事件 onclick ondblclick
变化事件 onchange
提交事件 onsubmit
加载事件 onload
当前组件 this

6.3 节点关系

HTML中的节点是有层次的,也就有父子关系。

parentNode和childNodes可以寻找当前节点的父节点和子节点。
previousSibling和nextSibling可以寻找当前节点的前一个或后一个同胞节点。

childNodes和children的区别:它们都可以获取一个元素的子节点,但children获取的节点中不包括文本节点,而childNodes包含文本节点。

6.4 创建节点

  • 创建元素节点 document.createElement(节点名)
  • 创建文本节点 document.createTextNode(文本内容)
  • 创建属性节点 document.createAttribute(属性名)

例如创建一个超链,链接文本是 www.12306.com,指向链接为 www.12306.com

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<script>
// 创建a标签
var a = document.createElement("a");
// 创建文本节点
var text = document.createTextNode("www.12306.com");
// 添加到a标签中
a.appendChild(text);
// 创建href属性
var href = document.createAttribute("href");
// 设置属性值
href.nodeValue = "www.12306.com";
// 将属性添加到a标签中
a.setAttributeNode(href);
</script>

6.5 删除节点

  • 删除元素节点 removeChild (先获取父节点,然后在父节点上删除该节点)
  • 删除属性节点 removeAttribute
  • 删除文本节点 childNodes[0]获取文本节点,再使用removeChild删除;innerHTML=””直接删除文本节点。

6.6 替换节点

replaceChild(节点1, 节点2) 在父节点上进行操作,节点1是保留的参数,节点2是被替换的节点。

6.7 插入节点

  • 追加节点 appendChild
  • 指定位置插入节点 insertBefore(节点1, 节点2) 在节点2前插入节点1

6.8 练习

6.8.1 练习01

在线观看

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
<html>
<head>
<meta http-equiv="Content-Type"content="text/html; charset=utf-8">
<title>DOM练习01</title>
</head>
<body>
<div>
<h3>1. 验证账号是否存在:使用简单地验证规则,如果账号以a或A开头,就提示已经存在</h3>
<input type="text" id="inputUser">
<input type="button" value="验证" onclick="checkAccount()">
<span style="color: lightcoral; display: none" id="noUser">账号已经存在</span>
<span style="color: lightgreen; display: none" id="yesUser">账号可以使用</span>
</div>
<div>
<h3>2. 切换不同的图片</h3>
<input type="button" value="通过src属性切换图片1" onclick="switch1()"><br>
<input type="button" value="通过属性节点切换图片2" onclick="switch2()"><br>
<img src="0.jpg" alt="" id="img">
</div>
<div>
<h3>3. 判断输入框里的值是否是整数(浮点数也不行)</h3>
<input type="text" id="num">
<input type="button" value="是否是整数?" onclick="judgeInt()">
<span id="result"> </span>
</div>
<script src="practice01.js"></script>
</body>
</html>

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
function getElement(id) {
var value = document.getElementById(id);
return value;
}

function checkAccount() {
var account = getElement("inputUser").value;
var noUser = getElement("noUser");
var yesUser = getElement("yesUser");
// 开始设置noUser和yesUser为不显示
noUser.style.display = "none";
yesUser.style.display = "none";

var firstChar = account.charAt(0);
if (0 == account.length){
noUser.style.display = "none";
yesUser.style.display = "none";
}else if ("a" == firstChar || "A" == firstChar) {
noUser.style.display = "inline";
}else {
yesUser.style.display = "inline";
}
}

function switch1() {
var img = getElement("img");
img.src = "1.jpg";
}

function switch2() {
var img = getElement("img");
img.attributes["src"].nodeValue = "0.jpg";
}

function judgeInt() {
var numStr = getElement("num").value;
var result = getElement("result");
if (0 == numStr.length) {
result.childNodes[0].nodeValue = "输入为空!";
} else {
var num = new Number(numStr);
if (isNaN(num) == true) {
result.childNodes[0].nodeValue = "输入包含非数字!";
} else {
var numList = numStr.split(".");
if (2 == numList.length) {
result.childNodes[0].nodeValue = "输入为小数!";
} else {
result.childNodes[0].nodeValue = "输入为整数~";
}
}
}
}

踩坑: 第三题刚开始做的时候一直有问题,如果html中的span标签中没有空格的话,即没有文本节点,那么用childNodes[0]是获取不到的,再通过其nodeValue修改值是行不通的。所以解决办法是设置空格,相当于有了文本节点;或者直接使用innerHTML修改内容节点的值。

6.8.2 练习02

在线观看

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
<html>
<head>
<meta http-equiv="Content-Type"content="text/html; charset=utf-8">
<link rel="stylesheet" href="style.css">
</head>
<body>
<h3>1. 鼠标移动到不同菜单时,显示不同的下拉菜单</h3>
<a href="#nowhere" class="d1" onmouseover="showMenu(this.className)">武器</a>
<a href="#nowhere" class="d2" onmouseover="showMenu(this.className)">护甲</a>
<a href="#nowhere" class="d3" onmouseover="showMenu(this.className)">英雄</a>
<div class="d d1">
<a href="#nowhere">大剑</a>
<a href="#nowhere">屠龙</a>
<a href="#nowhere">倚天</a>
<a href="#nowhere">七孔砖</a>
</div>
<div class="d d2">
<a href="#nowhere">胸甲</a>
<a href="#nowhere">护腕</a>
<a href="#nowhere">头盔</a>
<a href="#nowhere">鞋子</a>
</div>
<div class="d d3">
<a href="#nowhere">盖伦</a>
<a href="#nowhere">提莫</a>
<a href="#nowhere">安妮</a>
<a href="#nowhere">死歌</a>
</div>

<div style="margin-top: 200px;">
<h3>2. 当用户输入用户名时,就自动验证账号是否存在</h3>
<input type="text" id="inputUser" oninput="checkAccount()">
<span style="color: lightcoral; display: none" id="noUser">账号已经存在</span>
<span style="color: lightgreen; display: none" id="yesUser">账号可以使用</span>
</div>

<div style="margin-top: 50px;">
<h3>3. 点击全选,选中所有复选框;点击反选,反选复选框</h3>
<input type="checkbox" onclick="checkClick()">全选<br>
<input type="checkbox" class="check">tokyo hot<br>
<input type="checkbox" class="check">dota<br>
<input type="checkbox" class="check">lol<br>
<input type="checkbox" class="check">wow<br>
<input type="checkbox" class="check">warcraft<br>
<input type="checkbox" class="check">diablo<br>
<a href="#nowhere" onclick="reverseSelect()">反选</a>
</div>
<script src="practice02.js"></script>
</body>
</html>

CSS

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
a {
text-decoration: none;
}

.d {
color: lightgray;
border-style: solid;
border-color: lightgray;
border-width: 1px;
width: 80px;
display: none;
}

div.d a {
color: #888;
text-decoration: none;
font-family: 宋体;
display: block;
padding: 10 5 10 5;
}

div.d a:hover {
background-color: #f1f1f1;
}

div.d1 {
position: absolute;
left: 10px;
top: 80px;
}

div.d2 {
position: absolute;
left: 50px;
top: 80px;
}

div.d3 {
position: absolute;
left: 95px;
top: 80px;
}

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
function showMenu(className) {
var menu = document.getElementsByClassName(className)[1];
var totalMenu = document.getElementsByClassName("d");
for (var i = 0; i < totalMenu.length; i++) {
totalMenu[i].style.display = "none";
}
menu.style.display = "block";
}

function getElement(id) {
var value = document.getElementById(id);
return value;
}

function checkAccount() {
var account = getElement("inputUser").value;
var noUser = getElement("noUser");
var yesUser = getElement("yesUser");
// 开始设置noUser和yesUser为不显示
noUser.style.display = "none";
yesUser.style.display = "none";

var firstChar = account.charAt(0);
if (0 == account.length){
noUser.style.display = "none";
yesUser.style.display = "none";
}else if ("a" == firstChar || "A" == firstChar) {
noUser.style.display = "inline";
}else {
yesUser.style.display = "inline";
}
}

function checkClick() {
var checkboxes = document.getElementsByClassName("check");
for (var i = 0; i < checkboxes.length; i++) {
checkboxes[i].checked = true;
}
}

function reverseSelect() {
var checkboxes = document.getElementsByClassName("check");
for (var i = 0; i < checkboxes.length; i++) {
checkboxes[i].checked = ! checkboxes[i].checked;
}
}

6.8.3 练习03

在线观看

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
<html>
<head>
<meta http-equiv="Content-Type"content="text/html; charset=utf-8">
<link rel="stylesheet" href="style.css" type="text/css">
</head>
<body>
<div class="layout">
<p align="center">动态创建一个表</p>
id: <input type="text" id="ID">
名称: <input type="text" id="Name">
血量: <input type="text" id="HP">
伤害: <input type="text" id="damage"><br>
<center style="margin-top: 20px;"><input type="button" value="添加" onclick="addMessage()"></center>
<div id="dynamicTable">
<table>
<tr>
<td>id</td>
<td>名称</td>
<td>血量</td>
<td>伤害</td>
</tr>
</table>
</div>
</div>
<script src="practice03.js"></script>
</body>
</html>

CSS

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
div.layout {
margin: auto;
width: 550px;
padding: 100px;
}

input {
width: 80px;
}

td {
width: 150px;
text-align: center;
}

table {
margin-top: 20px;
border-bottom-style: solid;
border-bottom-width: 2px;
border-bottom-color: lightgray;
padding-bottom: 10px;
}

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
function addMessage() {
var id = getValue("ID");
var name = getValue("Name");
var hp = getValue("HP");
var damage = getValue("damage");

// 创建table元素
var tableElement = document.createElement("table");
// 创建tr元素
var trElement = document.createElement("tr");
// 创建td元素
var tdElement1 = document.createElement("td");
var tdElement2 = document.createElement("td");
var tdElement3 = document.createElement("td");
var tdElement4 = document.createElement("td");
// 创建文本节点
var idText = document.createTextNode(id);
var nameText = document.createTextNode(name);
var hpText = document.createTextNode(hp);
var damageText = document.createTextNode(damage);
// 添加到td元素中
tdElement1.appendChild(idText);
tdElement2.appendChild(nameText);
tdElement3.appendChild(hpText);
tdElement4.appendChild(damageText);
// 添加到tr元素中
trElement.appendChild(tdElement1);
trElement.appendChild(tdElement2);
trElement.appendChild(tdElement3);
trElement.appendChild(tdElement4);
// 添加到table元素中
tableElement.appendChild(trElement);

var div = document.getElementById("dynamicTable");
div.appendChild(tableElement);

// 清空输入框的值
document.getElementById("ID").value = null;
document.getElementById("Name").value = null;
document.getElementById("HP").value = null;
document.getElementById("damage").value = null;
}

function getValue(id) {
var value = document.getElementById(id).value;
return value;
}

可以用循环改进。。

6.8.4 练习04

动态加载js

在线观看

HTML

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<html>
<head>
<meta http-equiv="Content-Type"content="text/html; charset=utf-8">
</head>
<body id="parent">
<button onclick="dynamicJS()">动态加载js</button>
<button onclick="test()">动态加载js后点击才有效果</button>
<script>
function dynamicJS() {
// 创建script元素
var scriptElement = document.createElement("script");
// 创建属性节点
var src = document.createAttribute("src");
src.nodeValue = "practice04.js";
// 将属性添加到节点
scriptElement.setAttributeNode(src);

var body = document.getElementById("parent");
body.appendChild(scriptElement);
}
</script>
</body>
</html>

JavaScript

1
2
3
function test() {
alert("this is test.js");
}

6.9 常用场景

在线观看

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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
<html>
<head>
<meta http-equiv="Content-Type"content="text/html; charset=utf-8">
<style>
div.layout {
margin: auto;
padding: 50px;
width: 700px;
}
table {
border-collapse: collapse;
}
td {
border-style: solid;
border-width: 1px;
border-color: lightslategray;
width: 200px;
}
</style>
</head>
<body>
<div class="layout">
<div>
<h3>1. 删除行为前的提示</h3>
<p>在进行删除操作前,都应该提示用户是否要删除</p>
<table>
<tr>
<td>英雄名称</td>
<td>操作</td>
</tr>
<tr class="tr1">
<td>盖伦</td>
<td><a href="#nowhere" class="tr1" onclick="deleteData(this.className)">删除</a></td>
</tr>
<tr class="tr2">
<td>船长</td>
<td><a href="#nowhere" class="tr2" onclick="deleteData(this.className)">删除</a></td>
</tr>
<tr class="tr3">
<td>卡沙</td>
<td><a href="#nowhere" class="tr3" onclick="deleteData(this.className)">删除</a></td>
</tr>
</table>
</div>
<div>
<h3>2. 验证账号密码是否为空</h3>
<p>比如登录的时候,如果账号或密码为空,弹出提示,并且不提交(由于还没学服务器的知识,先不写表单提交的动作。)</p>
账号:<input type="text" id="user"><br>
密码:<input type="password" id="pwd"><br>
<input type="button" value="登录" onclick="isEmpty()">
</div>
<div>
<h3>3. 提交数据,验证长度</h3>
<p>比如注册用户名时,用户名至少需要3位长度</p>
账号:<input type="text" id="account"><br>
<input type="button" value="注册" onclick="judgeAccountLength()">
</div>
<div>
<h3>4. 验证年龄是否为数字</h3>
<p>比如注册的时候,需要提交年龄信息,用户输入的年龄信息必须是数字的(且不能是小数)。</p>
账号:<input type="text"><br>
年龄:<input type="text" id="age"><br>
<input type="button" value="注册" onclick="judgeAge()">
</div>
<div>
<h3>5. 验证Email格式是否正确</h3>
Email:<input type="text" id="email"><br>
<input type="button" value="注册" onclick="judgeEmail()">
</div>
<div>
<h3>6. 隐藏和显示</h3>
<input type="button" value="隐藏div" onclick="hide()">
<input type="button" value="显示div" onclick="show()"><br>
<div id="closable">这是一个div</div>
</div>
</div>
<script src="practice05.js"></script>
</body>
</html>

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
function deleteData(className) {
var flag = confirm("确定删除?");
if (flag) {
var trElement = document.getElementsByClassName(className)[0];
var parent = trElement.parentElement;
// 删除节点
parent.removeChild(trElement);
}
}

function isEmpty() {
var user = document.getElementById("user").value;
var pwd = document.getElementById("pwd").value;
if (0 == user.length) {
alert("用户名不能为空!");
} else if (0 == pwd.length) {
alert("密码不能为空!");
} else {
alert("登录成功!");
}
}

function judgeAccountLength() {
var account = document.getElementById("account").value;
if (3 > account.length) {
alert("用户名至少需要3位!");
} else {
alert("注册成功!");
}
}

function judgeAge() {
var age = document.getElementById("age").value;
if (0 == age.length) {
alert("年龄不能为空!");
} else {
var ageNum = new Number(age);
if (isNaN(ageNum)) {
alert("输入包含非法字符!");
} else {
var numList = age.split(".");
if (numList.length > 1) {
alert("输入包含小数!");
} else {
alert("注册成功!");
}
}
}
}

function judgeEmail() {
var email = document.getElementById("email").value;
var regEmail = /^(?:\w+\.?)*\w+@(?:\w+\.)*\w+$/;
var re = /^[a-zA-Z0-9_-]+@[a-zA-Z0-9\._-]+[a-zA-Z0-9_-]+$/;
if (re.test(email)) {
alert("注册成功!");
} else {
alert("请输入正确的邮箱格式!");
}
}

function hide() {
var div1 = document.getElementById("closable");
div1.style.display = "none";
}

function show() {
var div1 = document.getElementById("closable");
div1.style.display = "block";
}

踩坑:做 6.隐藏与显示 时,我开始使用的函数名是close(),发现不起作用,改为hide()便正常了。应该是close在js中是保留的关键字,不要使用它作为变量或函数名。类似的还有open和click。

7.排序问题:点击表头对表格内数据进行排序

在线观看

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
<html>
<head>
<meta http-equiv="Content-Type"content="text/html; charset=utf-8">
<link rel="stylesheet" href="style.css" type="text/css">
</head>
<body>
<div class="layout">
<p align="center">动态创建一个表</p>
id: <input type="text" id="ID">
名称: <input type="text" id="Name">
血量: <input type="text" id="HP">
伤害: <input type="text" id="damage"><br>
<center style="margin-top: 20px;"><input type="button" value="添加" onclick="addMessage()"></center>
<div id="dynamicTable">
<table>
<tr>
<td><a href="#nowhere" onclick="sort(0)">id</a></td>
<td><a href="#nowhere" onclick="sort(1)">名称</a></td>
<td><a href="#nowhere" onclick="sort(2)">血量</a></td>
<td><a href="#nowhere" onclick="sort(3)">伤害</a></td>
</tr>
</table>
</div>
</div>
<script src="practice06.js"></script>
</body>
</html>

CSS

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
div.layout {
margin: auto;
width: 550px;
padding: 100px;
}

input {
width: 80px;
}

td {
width: 150px;
text-align: center;
}

table {
margin-top: 20px;
border-bottom-style: solid;
border-bottom-width: 2px;
border-bottom-color: lightgray;
padding-bottom: 10px;
}

a {
text-decoration: none;
}

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
function addMessage() {
var id = getValue("ID");
var name = getValue("Name");
var hp = getValue("HP");
var damage = getValue("damage");

if (0 == id.length || 0 == name.length || 0 == hp.length || 0 == damage.length) {
alert("有选项未填写!");
} else {
// 创建table元素
var tableElement = document.createElement("table");

var className = document.createAttribute("class");
className.nodeValue = "sort";
tableElement.setAttributeNode(className);

// 创建tr元素
var trElement = document.createElement("tr");
// 创建td元素
var tdElement1 = document.createElement("td");
var tdElement2 = document.createElement("td");
var tdElement3 = document.createElement("td");
var tdElement4 = document.createElement("td");
// 创建文本节点
var idText = document.createTextNode(id);
var nameText = document.createTextNode(name);
var hpText = document.createTextNode(hp);
var damageText = document.createTextNode(damage);
// 添加到td元素中
tdElement1.appendChild(idText);
tdElement2.appendChild(nameText);
tdElement3.appendChild(hpText);
tdElement4.appendChild(damageText);
// 添加到tr元素中
trElement.appendChild(tdElement1);
trElement.appendChild(tdElement2);
trElement.appendChild(tdElement3);
trElement.appendChild(tdElement4);
// 添加到table元素中
tableElement.appendChild(trElement);

var div = document.getElementById("dynamicTable");
div.appendChild(tableElement);

// 清空输入框的值
document.getElementById("ID").value = null;
document.getElementById("Name").value = null;
document.getElementById("HP").value = null;
document.getElementById("damage").value = null;
}


}

function getValue(id) {
var value = document.getElementById(id).value;
return value;
}


var col = 0;
var reverse = false;
function sort(column) {
if (col == column) {
reverse = !reverse;
}
col = column;
var div = document.getElementById("dynamicTable");
// 提取出来Collection
var tableCollection = document.getElementsByClassName("sort");
// 因为Collection没有自带的排序函数,所以需要转换为数组,利用数组的排序。
var tables = new Array();
for (var i = 0; i < tableCollection.length; i++) {
tables.push(tableCollection[i]);
}
tables.sort(comparator);
for (var i = 0; i <tables.length; i++) {
div.appendChild(tables[i]);
}
}

function comparator(table1, table2) {
var td1 = table1.children[0].children[col].innerHTML;
var td2 = table2.children[0].children[col].innerHTML;
if (reverse) {
return td2.localeCompare(td1);
} else {
return td1.localeCompare(td2);
}
}

踩坑:数组的排序问题。自定义排序可以定义一个comparator函数,然后作为参数传到数组的sort方法中。关于comparator的排序定义是这样的,comparator(t1, t2)返回t1 - t2的话,表示按从小到大的顺序进行排列,因为t1大于t2的话,返回的是正值,t1就会拥有比t2要高的地位,放在t2的后面,形成从小到大的排序;而返回t2 - t1,则表示按照从大到小的顺序排列,因为此时需要t2大于t1,t1才会排在t2后面。

7. 参考