JavaWeb_04_JavaScript


本文介绍Web前端中的JavaScript相关知识。

1. JavaScript概述

JavaScript是运行在浏览器上的脚本语言,简称JS,是网景公司(NetScape)的布兰登艾奇开发的,最初叫做LiveScript。它的出现让浏览器更加的生动了,不再是单纯的静态页面了,页面更具有交互性。在历史的某个节点,SUN公司和网景公司之间有合作关系,SUN公司把LiveScript的名字修改为JavaScript,和Java没有任何关系,只是语法上有点类似。他们运行的位置不同,Java运行在JVM中,JavaScript运行在浏览器的内存当中。JavaScript程序不需要程序员手动编译,编写完源代码之后,浏览器直接打开解释执行。以普通文件形式保存,因此被称为“脚本语言”。

注意,JS和JSP没有关系,JSP是JavaServer Pages,隶属于Java语言,运行在JVM中;而JS运行在浏览器上。典型的VUE、AJAX和React等等,都是基于JS实现的高级框架。

JS主要包括三块:ECMAScript、DOM、BOM。

  • ECMAScript是ECMA指定的262标准,JavaScript和JScript都遵循这个标准,ECMAScript是JavaScript的核心语法。

  • DOM编程是通过JavaScript对HTML中的dom节点(document的缩写,节点就是标签)进行操作,DOM是有规范的,DOM规范是W3C制定的。

    DOM的全称是 Document Object Model,文档对象模型,对网页中的节点进行增删改的过程,HTML文档被当做一棵DOM树来看待。

  • BOM编程是对浏览器本身操作,例如:前进、后退、地址栏、关闭窗口、弹窗等等,由于浏览器有不同的厂家制造,所以BOM缺少规范,一般只有一个默认的行业规定。

    BOM的全称是Browser Object Model,浏览器对象模型,控制浏览器的一些动作。

BOM和DOM的区别和联系:

  • BOM的顶级对象是:window
  • DOM的顶级对象是:document(实际上是window.document,和window.alert类似,只不过window可以省略)
  • 实际上BOM是包括DOM的!

2. HTML嵌入JS代码

本质上JS和CSS一样,操作的主体是HTML中的标签。只不过CSS修饰的是标签的静态属性,而JS则是HTML的动态操作。所以JS也是要嵌入HTML代码中。

HTML中嵌入JS代码有如下三种方式。

2.1 属性内嵌

JS是一门事件驱动型的编程语言,依靠事件去驱动,然后执行对应的程序。在JS中有很多事件,其中有一个事件叫做:鼠标单击(click)。并且任何事件都会对应一个事件句柄(onclick)。注意,事件和事件句柄,事件句柄是在事件前面添加一个on;而事件句柄是以HTML标签的属性形式存在的。也就是说,如果某个标签设置了该某个事件句柄,那么只要该标签设置的事件句柄所对应的事件发生,就会执行该属性中的JS代码。简单例子如下所示:

1
2
3
4
<input type="button" value="hello" onclick="JS代码">

<!-- 页面打开的时候,JS代码并不会执行,只是把这段JS代码注册到按钮的click事件上了,等这个按钮噶生click事件之后,注册在onclick后面的JS代码会被浏览器自动调用 -->
<!-- 只要在hello按钮上触发了click事件,那么就会执行onclick属性对应的JS代码 -->

JS中的字符串可以使用单引号,也可以使用双引号,JS中的一条语句结束之后可以使用分号,也可以不用。

怎么使用JS代码弹出消息框?

在JS中有一个内置的对象叫做window,可以直接拿来使用,window代表的是浏览器对象。window对象有一个函数叫做:alert,用法是:window.alert(“消息”); 这样就可以弹窗了。如下所示:

1
<input type="button" value="hello" onclick="window.alert('Hello JS')">

即点击按钮,弹出消息框。注意,window. 可以省略不写

简单例子如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<!doctype html>
<html>
<head>
<title>HTML嵌入JS代码的第一种方式</title>
</head>

<body>

<!-- 点击按钮,实现弹出一个对话框 -->
<input type="button" value="hello1" onclick="window.alert('Hello JS1')"><br>

<input type="button" value="hello2" onclick="window.alert('Hello JS2')"><br>

<input type="button" value="hello3" onclick="window.alert('Hello JS3')
window.alert('asdf')
window.alert('zxcv')"><br>

</body>
</html>

2.2 脚本块

这种方式和CSS中的样式块类似,该脚本块可以放在HTML中的任何位置,遵循自上而下的执行顺序。没有特别说明,打开HTML页面就会自上而下执行HTML中的代码。JS脚本块出现的次数和位置均没有要求,注释和Java一样。语法结构如下所示:

1
2
3
<script type="text/javascript">
JS代码
</script>

简单例子如下所示:

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
<script type="text/javascript">
window.alert("first......")
</script>
<!doctype html>
<html>
<head>
<title>HTML嵌入JS代码的第一种方式</title>

<script type="text/javascript">
window.alert("head......")
</script>
</head>

<script type="text/javascript">
window.alert("cross......")
</script>

<body>

<!-- 点击按钮,实现弹出一个对话框 -->
<input type="button" value="hello1"><br>

<script type="text/javascript">
window.alert("body......")
</script>

<input type="button" value="hello2"><br>
</body>

<script type="text/javascript">
window.alert("after body......")
</script>
</html>

<script type="text/javascript">
window.alert("end......")
</script>

注意,不同的浏览器的效果可能略有差异。

逻辑上,上面的代码,打开网页后,先弹出first消息框,然后再弹出head消息框,然后弹出cross框,然后再出现hello1按钮,然后弹出body消息框,然后出现hello2按钮,然后弹出after body消息框,然后弹出end消息框。

所以,alert消息框会阻塞HTML页面的加载。

2.3 链入文件

和CSS一样,JS代码可以单独写入一个文件中,后缀名为.js,文件中编写JS代码即可。然后在HTML页面中,在需要的位置引入JS脚本文件,引入外部独立的JS文件的时候,JS文件中的代码会遵循自上而下的顺序依次逐行执行。一个文件可以被引入多次。引入文件的语法结构如下所示:

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

注意,如果引入了JS文件,那么该标签内的JS脚本块代码是不会执行的。简单例子如下所示:

1
2
<!-- JS文件:js01.js -->
window.alert("hello world")
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<!-- html代码 -->

<!doctype html>
<html>
<head>
<title>HTML嵌入JS代码的第一种方式</title>
</head>

<body>

<input type="button" value="hello1"><br>

<input type="button" value="hello2"><br>

<script type="text/javascript" src="js01.js"></script>
</body>

</html>

3. 标识符和关键字

作为脚本语言,JS也存在其他编程语言的相关术语,比如标识符和关键字等等,如标识符由字母数字下划线和美元符号组成等等。JS的命名规则以及规范和Java类似,可以按照Java的标准来,这里不再赘述。

4. 变量

Java语言是一种强类型语言。Java语言存在编译阶段,程序在编译阶段就已经确定了变量的数据类型,那么这个变量到最终内存释放,就一直是这个类型,不可能变成其他类型。编译期强行固定变量的数据类型,称为强类型语言。

而JS则是一种弱类型语言,没有编译阶段,一个变量可以随意赋值(类似Python),声明变量以及赋值的语法结构如下所示:

1
2
3
4
5
6
7
var 变量名;
变量名 = 值;

var i;
var k = undefined;
window.alert(i);
window.alert(k);

变量的默认值为:undefined。如果一个变量没有声明/定义,直接访问,会报错。注意,这个报错,可能不会在网页中显示,但是可以通过在网页中按F12点击控制来进行查看错误。简单案例如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<!DOCTYPE html>
<html>
<head>
<title> 联系JavaScript </title>
</head>
<body>

<script type="text/javascript">

var i;
var k = undefined;

alert("i = " + i);
alert(k);

alert(age);
</script>
</body>
</html>

js_01.png (1214×202) (gitee.io)

4.1 局部变量和全局变量

JS中的变量也分为局部变量和全局变量。

  • 全局变量:

    在函数体之外声明的变量属于全局变量,全局变量的声明周期是:浏览器打开时声明,浏览器关闭时销毁。因为全局变量会一直在浏览器的内存当中,耗费内存空间,能使用局部白能量尽量使用局部变量。

  • 局部变量:

    在函数体中声明的变量,包括一个函数的形参,都属于局部变量,局部变量的声明周期是:函数开始执行时局部变量的内存空间开辟,函数执行结束之后,局部变量的内存空间释放。局部变量声明周期较短。

  • 注意,如果一个变量在声明的时候,没有采用var关键字,那么这个变量无论是在哪里定义的,都是全局变量。

利用下面的函数对二者进行测试:

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
var i = 10;

function accessI(){
i = i + 1;
alert("in accessI: " + i);
}

accessI();

alert("after accessI: " + i);

var userName = "jack";

function accessUaerName(){
var userName = "hash";
alert(userName);
}

accessUaerName();

alert(userName);

function myfun(){
// 注意,如果一个变量在声明的时候没有采用var,那么这个变量就是全局变量。
myName = "asdf";
}

alert(myName);

5. 函数

JS中的函数等同于Java语言中的方法,函数也是一段可以被重复利用的代码片段,函数一般都是可以完成某个特定功能的。JS的函数有两种定义格式:

  • 第一种方式

    1
    2
    3
    function 函数名(形式参数列表){
    函数体;
    }
  • 第二种方式

    1
    2
    3
    函数名 = function(形式参数列表){
    函数体;
    }

JS中的函数不需要指定返回值类型,返回什么类型都可以。简单例子如下所示;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function sum(a, b){
alert(a + b);
}

function sums(a, b){
return a + b;
}

sum(10, 20);
alert(sums(20, 40));

sum("asdf", "zxcv");

sum("dfghd");

sum();

sum(1);

sum(1, 2, 3);

注意,在JS中,如果两个函数重名的话,不管参数列表如何,后面的函数会将前面的函数覆盖掉,即谁后声明谁就有效。

6. 数据类型

虽然JS中的变量在声明的时候不需要指定数据类型,但是在赋值的时候,每一个数据还是有类型的,所以这里也需要学习一下JS包括哪些数据类型。JS中数据类型有原始类型和引用类型两种。

  • 原始类型

    Undefined、Number、String、Boolean、Null。

  • 引用类型

    Object以及子类。

JS中有一个运算符叫做typeof,这个运算符可以在程序的运行阶段动态的获取变量的数据类型。语法结构如:typeof 变量名,运算结果是一下6个字符串之一,注意字符串都是全部小写:“undefined”, “number”, “string”, “boolean”, “object”,“function”。

在JS中比较字符串是否相等使用双等号判断。简单例子如下所示:

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
<!DOCTYPE html>
<html>
<head>
<title>JS数据类型</title>
</head>
<body>

<script type="text/javascript">
function sum(a, b){

if(typeof a == "number" && typeof b == "number"){
return a + b;
}

alert(a + "," + b + "必须都为数字!");
}

// 注意,如果此处函数没有返回值,alert不算返回值,那么result就是undefined。
var result = sum("asdf", 23);
alert(result);

// sum("as", "q2wer");


var i;
alert(typeof i); // undefined

var k = 10;
alert(typeof k); // number

var f = "abc";
alert(typeof f); // string

var d = null;
alert(typeof d); // object,注意,虽然 null 值的NUll类型,但是typeof输出结果是object。

var flag = false;
alert(typeof flag); // boolean

var obj = new Object();
alert(typeof obj); // object

alert(typeof sum); // function

</script>
</body>
</html>

6.1 原始类型

6.1.1 Undefined

Undefined类型只有一个值,这个值就是 undefined,当一个变量没有手动赋值,系统就会默认赋值 undefined,或者也可以手动给一个变量赋值 undefined。简单例子如下所示:

1
2
3
4
5
6
var i;
var k = undefined;
var c = "undefined";

alert(i == k);
alert(k == c);

6.1.2 Number

Number类型包括很多值,所有的数字都是,还有NaN(非数字)和Infinity(无穷大)。

什么情况下结果是一个NaN呢?运算结果本来应该是一个数字,最后运算完不是一个数字的时候,结果是NaN。

什么情况下结果是一个Infinity呢?当除数为0的时候,结果为无穷大。

简单例子如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
var v1 = 1;
var v2 = 3.14;
var v3 = -100;
var v4 = NaN;
var v5 = Infinity;
var v6 = 100 / "中国人";

alert(typeof v1);
alert(typeof v2);
alert(typeof v3);
alert(typeof v4);
alert(typeof v5);

alert(typeof v6);
alert(v6);

alert(10 / 0);
alert(10 / 3);

关于Number数据类型的相关函数如下所示:

函数名 描述
isNaN(数据) 结果为true表示不是一个数字。
parseInt() 将字符串转换成数字,取整数位,也可以对小数取整数位。
parseFloat() 将字符串转换成数字,并转换成浮点数。
Math.ceil() 向上取整。Math是数学类,数学类中有一个函数叫做ceil。

简单例子如下所示:

1
2
3
4
5
6
7
8
alert(parseInt(3.234));
alert(parseInt("4.234"));

alert(parseFloat(3));
alert(parseFloat("3.1234"));

alert(Math.ceil("2.1234"));
alert(Math.ceil(2.1234));

6.1.3 Boolean

JS中的布尔类型永远都只有两个值:true 和 false。**在Boolean类型中有一个函数叫做:Boolean()**。语法格式是:Boolean(数据),作用是将非布尔类型转换成布尔类型。

注意,if条件中,如果条件不是布尔类型,会自动调用布尔函数,将其转换为布尔值,所以下面的Boolean其实不用写也可以,简单例子如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var username = "";

if(Boolean(username)){
alert("欢迎你:" + username);
}else{
alert("用户名不能为空!");
}

alert(Boolean(1)); // true
alert(Boolean(0)); // false
alert(Boolean("")); // false
alert(Boolean("asdf")); // true
alert(Boolean(null)); // false
alert(Boolean(NaN)); // false
alert(Boolean(undefined)); // false
alert(Boolean(Infinity)); // true

6.1.4 String

在JS中,字符串可以使用单引号,也可以使用双引号。JS创建字符串对象有两种方式,如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 第一种方式:
var s = "asdf";
var ss = 'asdf';

// 第二种方式,使用JS内置的支持类String.
// 注意,String是一个内置的类,可以直接使用,String的父类是Object。
var sss = new String("asdf");

// 小string类型。
alert(typeof s); // string
alert(typeof ss); // string

// 大string类型(本质上属于Object类)
alert(typeof sss); // object

alert(s.length);
alert(ss.length);
alert(sss.length);

注意,无论是小string还是大string类型,二者的属性和方法都是通用的。另外,String对象有一些常用的方法,参考担当即可,这里不再赘述。

6.2 引用类型

6.2.1 Object

和Java一样,Object类型是所有类型的父类,自定义的任何类型,默认继承Object,会继承Object类中所有的属性和函数。该类有prototype和constructor两个属性,toLocaleString、toString和valueOf三个方法。重点掌握prototype这个属性即可。这个属性的作用是给类动态的扩展属性和函数。

6.2.1.1 自定义类

类的定义方式和函数的定义方式一样,只不过如果采用new 函数名的方式,那么就会自动把定义函数的语法看成是定义类;而如果采用调用函数名的方式,则会把定义函数的语法看成是定义函数。在JS中,类的定义同时也是一个构造函数的定义。二者是放在一起来完成的。

定义类的语法有如下两种形式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 第一种
function 类名(形参){

}

// 第二种
类名 = function(形参){

}

// 把上述方法看成是定义类
new 类名();

// 把上述方法看成是定义函数,即当成是一个普通函数。
类名();
6.2.1.2 创建对象

创建对象的语法如下:

1
new 类名(实参);	// 构造方法名和类名一致。
6.2.1.3 简单案例
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
function User(a, b, c){
// 声明属性,this表示当前对象。User类中有三个属性
this.sno = a;
this.sname = b;
this.sage = c;

// 类函数
this.getSage = function(){
return this.sage;
}
}

// 创建对象
var u1 = new User(111, "zhangSan", 30);

// 访问对象的属性
alert(u1.sno);
alert(u1.sname);
alert(u1.sage);
alert(u1.getSage());

alert(u1["sno"]);
alert(u1["sname"]);
alert(u1["sage"]);
alert(u1.getSage());
6.2.1.4 通过prototype这个属性给类动态扩展属性和函数

通过类的这个属性来动态设置这个类的属性和函数。比如依然是上面的类,新增getSname()函数和sheight属性。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
User.prototype.getSname = function() {
return this.sname;
}

User.prototype.sheight;

alert(u1.getSname());
alert(u1.sheight);

// 给String类扩展函数
String.prototype.suiyi = function(){
alert("这是给String类扩展的一个个函数");
}

"asdf".suiyi();

6.3 null、NaN和undefined三个的区别

注意,在JS中有两个比较特殊的运算符,双等号和三等号:

  • ==,双等号用于判断值是否相等。
  • ===,三等号即判断是否相等,也判断数据类型是否一致。
1
2
3
4
5
6
7
8
9
alert(typeof null);		// object
alert(typeof NaN); // number
alert(typeof undefined); // undefined

alert(null == NaN); // false
alert(null == undefined); // true
alert(NaN == undefined); // false

alert(null === undefined); // false

6.4 运算符

JS的运算符和Java大致类似,这里不再赘述,只讲解void运算符。

语法格式:void(表达式)这个运算符的作用是执行表达式,但不返回任何结果。简单案例如下所示:

需求:既保留住超连接的样式,同时用户点击该插连接的时候执行一段JS代码,但该页面还不能跳转(即仍然是当前页面的当前位置)。注意,即使当前路径填写的是空路径,也会重新跳转,这样,就不会保留当前页面的当前位置了。

所以,可以采用 void运算符,即点击超链接的时候,执行该运算符,没有结果就不会跳转了。**还要注意,需要告诉HTML这里的void运算符是JS代码,即在前面加上 javascript: **

因为目的就是不返回任何结果,所以void括号中的表达式是什么都行,不依赖表达式的执行过程。其实目的就是将超链接修改为’空’路径,没有路径可以跳转

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<!DOCTYPE html>
<html>
<head>
<title>联系JS</title>
</head>
<body>
页面顶部<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<a href="javascript:void(0)" onclick="window.alert('test code')">
既保留住超连接的样式,同时用户点击该插连接的时候执行一段JS代码,但该页面还不能跳转(即仍然是当前页面的当前位置)。
注意,即使当前路径填写的是空路径,也会重新跳转,这样,就不会保留当前页面的当前位置了。
</a>
<br><br><br><br>
</body>
</html>

7. 事件

前面提到过,JS可以是事件驱动的,那么JS的常用事件如下所示:

事件 描述
blur 失去焦点(光标由在这里到不在这里)
focus 获得焦点(光标由不在这里到在这里)
click 鼠标单击
dblclick 鼠标双击
keydown 键盘按下
keyup 键盘弹起
mousedown 鼠标按下
mouseover 鼠标经过
mousemove 鼠标移动
mouseout 鼠标离开
mouseup 鼠标弹起
reset 表单重置
submit 表单提交
change 下拉列表选中项改变,或文本框内容改变
load 页面加载完毕
select 文本被选定(即用鼠标滑动选中文本,类似复制的操作)

注意,任何一个事件都会对应一个事件句柄,事件句柄是在事件前添加on,用于作为标签的属性。

注册事件指的是在HTML中设置事件的时间句柄,用于后续触发事件时执行响应的操作。这个操作也就是JS脚本函数,称为回调函数(callback函数)。浏览器在调用该函数的时候会给该函数传参:事件对象。如果回调函数不需要这个参数,可以不用写实参来接收。回调函数的特点:自己把这个函数代码写出来了,但是这个函数不是自己负责调用,由其他程序负责调用该函数。简单例子如下所示:

1
2
3
4
5
6
7
8
9
10
11
<scrip type="text/javascript">
function sayHello(){
alert("hello js");
}
</scrip>

<input type="button" value="hello" onclick="sayHello()"/>

<!--此时再input标签中写了click事件的事件句柄onclick,这就叫做注册事件-->
<!--因为sayHello函数只有click事件触发的时候,才会调用,而且调用者是浏览器,并不是我们程序员,所以该从我们自己的角度来看,该函数是回调函数。 -->
<!--也就是说该函数此刻仅仅是注册到按钮上,等待click事件触发时才会被调用。-->

7.1 注册事件的两种方式

一种是上面提到的在标签的属性那里注册事件,但是一般情况下,HTML和JS代码要尽可能的分离,所以可以采用第二种方式,在JS代码中获得标签对象,并设置该标签的事件句柄属性。如下所示:

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
<input type="button" value="hello1" onclick="sayHello()">
<input type="button" value="hello2" id="mybtn2"/>
<input type="button" value="hello3" id="mybtn3"/>
<input type="button" value="hello4" id="mybtn4"/>

<script type="text/javascript">
function sayHello(){
alert("hello js");
}

function doSome(){
alert("do some!");
}

// 第一步,先获取标签对象,(document是全部小写,内置对象,可以直接用,document就代表整个HTML页面)
var btnObj = document.getElementById("mybtn2");

// 第二部,给按钮对象的事件句柄属性赋值回调函数,直接赋值即可,不需要添加。
btnObj.onclick = doSome; // 注意,这里不需要加小括号。

// 也可以以匿名函数的形式来注册事件。
var btnObj3 = document.getElementById("mybtn3");
btnObj3.onclick = function(){
alert("asdfasdfasdfasdfasdfasdf");
}

// 推荐这么写
document.getElementById("mybtn4").onclick=function(){
alert("qwerqwerqwerqwerqwerqwer");
}
</script>

7.2 JS代码的执行顺序

前面提到过,只要打开HTML文件,就会自上而下的执行代码,包括JS代码(仅仅是注册时事件,并不是真正执行)。那么对于上面的例子,加入JS代码写到了某些标签的前面,此时,在注册事件的时候,因为找不到该标签而发生错误(因为自上而下执行,所以该JS代码在执行的时候,标签还没有加载):Uncaught TypeError: Cannot set properties of null (setting 'onclick')

一种解决办法是将JS代码写到HTML文档的最后面,但是这种方法不符合规范。有一种事件叫做页面加载完毕事件(load),所以可以设置该事件,只有当页面加载完毕后再进行事件绑定即可。简单案例如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<!DOCTYPE html>
<html>
<head>
<title>联系JS</title>
</head>
<body onload="ready()">
<script type="text/javascript">

function ready(){
document.getElementById("mybtn").onclick = function(){
alert("asdfasdfasdf");
}
}

</script>
<input type="button" value="test" id="mybtn"/>
</body>
</html>

除了之外,还有另一种load事件的注册方式:

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
<!DOCTYPE html>
<html>
<head>
<title>联系JS</title>
</head>
<body>
<script type="text/javascript">

window.onload = ready;

function ready(){
document.getElementById("mybtn").onclick = function(){
alert("asdfasdfasdf");
}
}

// 或者如下方式
// window.onload = function(){
// document.getElementById("mybtn").onclick = function(){
// alert("asdfasdfasdf");
// }
// }

</script>
<input type="button" value="test" id="mybtn"/>
</body>
</html>
  • 页面加载的过程中,将ready函数注册给了load事件
  • 页面加载完毕(load事件触发),执行ready函数,将onclick事件注册到按钮中。
  • 点击按钮,触发click事件,执行该函数。
  • 注意,load事件不需要手动触发,页面加载完毕自动触发

7.3 简单案例

单击按钮,将文本框修改为复选框。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<!DOCTYPE html>
<html>
<head>
<title>联系JS</title>
</head>
<body>
<script type="text/javascript">

window.onload = ready;

function ready(){
document.getElementById("mybtn").onclick = function(){
// 标签有什么属性就可以直接调用什么属性
var text = document.getElementById("mytext");
text.type="checkbox";
}
}

</script>
<input type="text" id="mytext">
<input type="button" value="test" id="mybtn"/>
</body>
</html>

7.4 键盘事件以及捕捉

以回车键为例,一般情况下,输入账号密码后,在密码框中直接按下回车键就会自动登录,这是怎么做到的呢?JS代码捕捉到回车键按下事件,再执行相应操作即可。这里JS函数中用到了键盘事件,所以JS函数需要写形参来接收。简单案例如下所示:

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
<!DOCTYPE html>
<html>
<head>
<title>联系JS</title>
</head>
<body>
<script type="text/javascript">
window.onload = function(){
var pwdElt = document.getElementById('password');

pwdElt.onkeydown = function(event){
// event 是形参,用于接收浏览器调用时传过来的事件对象实参。
// 注意,因为JS是弱语言,所以形参和实参可以不对应,所以之前写的function没有形参也可以。
// alert(event);

// 判断是否是回车键按下
// 每个键都有值,回车键的键值是13,ESC的键值是27。
// 键盘事件有keyCode属性,用于获取键值。
//alert(event.keyCode);

if(event.keyCode == 13){
alert("正在验证...");
}
}
}
</script>

账号:<input type="text" id="username" /><br>
密码:<input type="text" id="password" />
</body>
</html>

8. 控制语句

JS中的控制语句有如下几种:

  • if
  • switch
  • while
  • do…while
  • for循环
  • break
  • continue
  • for…in语句(了解)
  • with语句(了解)

前面几种和Java的语法一样,这里不再赘述,主要讲解后面两种。JS中的数组和Python类似,中括号,可以存储任意数据类型,自动扩容。

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
var arr = [false, true, 1, 2, 3.14, "abc"];

for(var i=0; i < arr.length; i++){
alert(arr[i]);
}

alert("第二种for循环");

for(var i in arr){
// 如果遍历对象是数组,那么i 是 下标
alert(arr[i]);
}

User = function(username, password){
this.username = username;
this.password = password;
}

var u = new User("zhagnsan", "asdf");
alert(u.username + "," + u.password);
alert(u["username"] + "," + u["password"]);

for(var field in u){
// 如果遍历对象是 对象,那么遍历的就是其属性
alert(u[field]);
}

alert("with关键字");
with(u){
// with 关键字,自动将u加到后续属性的前面
alert(username + "," + password);
}

9. DOM编程

上面的2~8部分其实是ECMAScript规范,本节讲解DOM编程,DOM编程是针对标签的一系列操作。

9.1 获取以及修改文本框的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
27
28
29
30
31
<!DOCTYPE html>
<html>
<head>
<title>DOM编程</title>
</head>
<body>
<script type="text/javascript">

window.onload = function(){

var myBtn = document.getElementById('myBtn');

myBtn.onclick = function(){
alert(document.getElementById('username').value);
document.getElementById("verify").value = document.getElementById("username").value;
}


}

</script>

用户名:<input type="text" id="username" />
<input type="button" value="获取" id="myBtn"><br>

确认信息:<input type="text" id="verify"><br>

<!-- blur 事件,功能:只要光标一离开,就弹出当前标签的值的窗口-->
<input type="text" onblur="alert(this.value)">
</body>
</html>

9.2 操作div和span

设置div和span中的内容主要是用到innerHTMLinnerText两个属性,简单例子如下所示:

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>
<title>
DOM编程
</title>
<style type="text/css">
#div1{
background-color: aquamarine;
width: 300px;
height: 300px;
border: 1px black solid;
position: absolute;
top: 100px;
left: 100px;
}
</style>
</head>
<body>
<script type="text/javascript">
window.onload = function(){

var myBtn = document.getElementById("myBtn");
myBtn.onclick = function(){

var div1 = document.getElementById("div1");
// div1.innerHTML = "asdfasdfasdfasdfasdfasdf";
// div1.innerHTML = "<font color='red'>用户名不能为空!</font>";

div1.innerText = "<font color='red'>用户名不能为空!</font>";

}
}
</script>

<input type="button" value="设置div内容" id="myBtn">
<div id="div1"></div>
</body>
</html>

注意,innerText和innerHTML属性有什么区别?

  • 相同点:都是设置元素内部的内容
  • 不同点:
    • innerHTML会把后面的“字符串”当做一段HTML代码解释并执行
    • innerText会把后面的“字符串”当做一段普通字符串来看待。

9.3 正则表达式

正则表达式的全称是Regular Expression,主要用于字符串格式匹配方面。正则表达式实际上是一门独立的学科,在各种编程语言中都支持,最初使用在医学方面,用来表示神经符号等。目前使用最多的是计算机编程领域,用作字符串格式匹配,包括搜索方面。

一般情况下,常用的正则表达式匹配串都有现成的,直接网络搜索即可,我们只需要掌握常见的正则表达式符号以及能够看懂即可。

9.3.1 常见的正则表达式符号

符号 含义
. 匹配除换行符意外的任意字符
\w 匹配字母或数字或下划线或汉字
\s 匹配任意的空白符
\b 匹配单词的开始或结束
^ 匹配字符串的开始
$ 匹配字符串的结束
* 重复零次或多次
+ 重复一次或多次
重复零次或一次
{n} 重复n次
{n, } 重复n次或更多次
{n, m} 重复n到m次

还有如下所示

操作符 说明 实例
. 表示任何单个字符(换行符除外)
[] 字符集,对单个字符给出取值范围 [abc]表示a、b、c,[a-z]表示a到z单个字符
[^] 非字符集,对单个字符给出排除范围 [^abc]表示非a或b或c的单个字符
* 前一个字符0次或无限次扩展 abc*表示ab、abc、abcc、abccc等,c的0次或无限次
+ 前一个字符1次或无限次扩展 abc+表示abc、abcc、abccc等
? 前一个字符0或1次扩展 abc?表示ab、abc
| 左右表达式任意取一个 abc|def表示abc或def
{m} 扩展前一个字符m次 ab{2}c表示abbc
{m, n} 扩展前一个字符m至n次(含n) ab{1, 2}c表示abc,abbc
^ 匹配字符串开头(前提是没有在方括号中) ^abc表示abc且在一个字符串的开头
$ 匹配字符串结尾 abc$表示abc且在一个字符串的结尾
() 分组标记,内部只能使用 | 操作符 (abc)表示abc,(abc|def)表示abc、def
\d 数字,等价于[0-9]
\w 单词字符,等价于[A-Za-z0-9_]

9.3.2 常见的正则表达式

9.3.3 JS创建正则表达式

JS创建正则表达式对象有两种方式

  • var re = /正则表达式/flags
  • var re = new RegExp("正则表达式", "flags")

flags主要有三种取值(可以省略不写):

  • g,全局匹配
  • i,区分大小写匹配
  • m,多行匹配(不掌握,了解,当前面的正则表达式不是纯字符串的时候,可以用,如果是纯字符串,那么不能用。)

正则表达式对象的text()方法?用法如下所示:正则表达式对象.text(要匹配的字符串),返回结果为true和false,true表示表示匹配,false表示不匹配。简单例子如下所示:

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
<!DOCTYPE html>
<html>
<head>
<title>正则表达式</title>
</head>
<body>
<script type="text/javascript">
window.onload = function(){

// 给按钮绑定click
var btn = document.getElementById("btn");
btn.onclick = function(){

var email = document.getElementById("email").value;
var emailRegExp = /^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/;
var ok = emailRegExp.test(email);
if(!ok){
document.getElementById("emailError").innerText = "邮箱地址不合法";
}else{
document.getElementById("emailError").innerText = "邮箱地址合法";
}
}

// 给文本框绑定focus
document.getElementById("email").onfocus = function(){
document.getElementById("emailError").innerText = "";
}

}
</script>

邮箱:<input type="text" id="email" />
<span id="emailError" style="color: red; font-size: 12px;"></span><br>
<input type="button" value="验证邮箱" id="btn" />
</body>
</html>

9.4 表单验证

需求如下:

  1. 用户名不能为空
  2. 用户名必须在6-14位之间
  3. 用户名只能由数字和字母组成,不能含有其他符号(正则表达式)
  4. 密码和确认密码一致,邮箱地址合法
  5. 统一失去焦点验证
  6. 错误提示信息统一在span标签中提示,并且要求字体12号,红色
  7. 文本框再次获得焦点后,清空错误提示信息,如果文本框中数据不合法要求清空文本框的value
  8. 最终表单中所有项均合法方可提交

注意,最后一项,提交表单的时候需要验证所有项是否均合法,也就是提交前需要验证:一种解决办法是将现有的提交按钮修改为普通按钮,然后注册点击事件,进行相关操作。

判断是否合法的一个方法就是根据后面的span中是否有内容,如果有内容,则肯定是不合法的。但是页面刚开始打开的时候,span也是空的,所以首先要触发检测事件,让span先判断一遍。简单例子如下所示:

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
<!DOCTYPE html>
<html>
<head>
<title>表单验证</title>
</head>
<body>
<script type="text/javascript">

window.onload = function(){

// 用户名
var username = document.getElementById("username");
var usernameSpan = document.getElementById("usernameSpan");
username.onblur = function(){
if(username.value.length == 0){
usernameSpan.innerText = "用户名不能为空";
}else if(username.value.length < 6 || username.value.length > 14){
usernameSpan.innerText = "用户名长度必须在6-14位之间";
}else{
// 正则表达式验证用户名只能有数字和字母组成。
var regExp = /^[A-Za-z0-9]+$/;
if(!regExp.test(username.value)){
usernameSpan.innerText = "用户名只能由字母或数字组成"
}
}
}

username.onfocus = function(){
if(usernameSpan.innerText != ""){
username.value = "";
}

usernameSpan.innerText = "";
};

// 密码
var password = document.getElementById("password");

// 确认密码
var verify = document.getElementById("verify");
var verifySpan = document.getElementById("verifySpan");
verify.onblur = function(){
if(verify.value == "" || password.value != verify.value){
verifySpan.innerText = "确认密码和密码不一致";
}
}

verify.onfocus = function(){

if(verifySpan.innerText != ""){
verify.value = "";
}

verifySpan.innerText = "";
}

// 邮箱
var email = document.getElementById("email");
var emailSpan = document.getElementById("emailSpan");
var emailRegExp = /^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/;
email.onblur = function(){
if(!emailRegExp.test(email.value)){
emailSpan.innerText = "邮箱名不合法";
}
}
email.onfocus = function(){

if(emailSpan.innerText != ""){
email.value = "";
}

emailSpan.innerText = "";
}

// 重置
document.getElementById("reset").onclick = function(){
usernameSpan.innerText = "";
verifySpan.innerText = "";
emailSpan.innerText = "";
}

// 提交按钮
var submitBtn = document.getElementById("submitBtn");
submitBtn.onclick = function(){

// 触发上面的blur事件,保证上述表单已经检查过信息。这样,就能保证后面的span已经可以有信息了,然后再判断信息是否为空即可。
username.focus();
username.blur();

verify.focus();
verify.blur();

email.focus();
email.blur();

// 判断span信息
if(usernameSpan.innerText == "" && verifySpan.innerText == "" ** emailSpan.innerText == ""){

// 手动提交信息
var formElt = document.getElementById("userForm");
formElt.submit();
}

}
}

</script>

<form action="http://localhost:8080/js/save" method="get" id="userForm">
用户名:<input type="text" name="username" id="username" /><span id="usernameSpan" style="color: red; font-size: 12px;"></span><br>
密码:<input type="password" name="password" id="password"><br>
确认密码:<input type="password" id="verify"><span id="verifySpan" style="color: red; font-size: 12px;"></span><br>
邮箱:<input type="text" name="email" id="email"><span id="emailSpan" style="color: red; font-size: 12px;"></span><br>

<input type="button" value="注册". id="submitBtn">
<input type="reset" value="重置" id="reset">
</form>

</body>
</html>

9.5 复选框的全选和取消全选

首先复选框,点击全选按钮,下面的子复选框全部选中或者全部取消选中;另外,如果当前选中的复选框的数量和全部数量一致,那么全选按钮则自动选中,否则,自动取消。

简单例子如下所示:

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
<!DOCTYPE html>
<html>
<head>
<title>复选框的全选和取消全选</title>
</head>
<body>
<script type="text/javascript">
window.onload = function(){
var allBtn = document.getElementById("all");
var aihaos = document.getElementsByName("aihao"); // 根据name属性获取名字为name的全部标签对象
allBtn.onclick = function(){

// 根据全选按钮的是否选中状态,判断接下来的操作,如果没有全选,点击全选,则下面的三个复选框均设置选中
// 注意,因为是点击按钮事件,所以只要点击了,那么当前的按钮就是选中了(实际上,这个事件触发前就是没选中状态),
// 所以此时是要 全选,即设置下面的复选框均为选中状态
// 否则,则是曲线全选状态。

// if(allBtn.checked){
// // 全选
// for(var i=0; i < aihaos.length; i++){
// aihaos[i].checked = true;
// }

// }else{
// // 取消全选
// for(var i=0; i < aihaos.length; i++){
// aihaos[i].checked = false;
// }
// }

// 上述的简化方法,即下面的复选框直接跟随全选按钮的状态即可。
for(var i=0; i < aihaos.length; i++){
aihaos[i].checked = allBtn.checked;
}
}

// 还有一个要点,点击下面的复选框,上面的全选按钮要取消选中状态。以及,如果复选框都选中的话,全选按钮要自动选中。
// 另外,不知道复选框有多少个,直接遍历即可。
var all = aihaos.length;
for(var i=0; i < aihaos.length; i++){
aihaos[i].onclick = function(){

var checkCount = 0;
for(var j=0; j < aihaos.length; j++){
if(aihaos[j].checked){
checkCount++;
}
}

// if(checkCount == all){
// allBtn.checked = true;
// }else{
// allBtn.checked = false;
// }

// 上述if判断精炼
allBtn.checked = (all == checkCount);
}
}
}
</script>
<input type="checkbox" id="all">全选<br>
<input type="checkbox" name="aihao" value="smoke">抽烟<br>
<input type="checkbox" name="aihao" value="drink">喝酒<br>
<input type="checkbox" name="aihao" value="tt">烫头<br>
</body>
</html>

9.6 获取下拉列表选中项的value

这个比较简单,直接注册change事件获取值即可。

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
<!DOCTYPE html>
<html>
<head>
<title>联系JS</title>
</head>
<body>
<script type="text/javascript">
window.onload = function(){
var selectElt = document.getElementById("slt");

selectElt.onchange = function(){
alert(selectElt.value);
}

}
</script>
<select id="slt">
<option value="">--请选择省份--</option>
<option value="hb">河北省</option>
<option value="hn">河南省</option>
<option value="sd">山东省</option>
<option value="sx">山西省</option>
</select>
</body>
</html>

或者也可直接JS嵌入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!DOCTYPE html>
<html>
<head>
<title>联系JS</title>
</head>
<body>
<select onchange="alert(this.value)">
<option value="">--请选择省份--</option>
<option value="hb">河北省</option>
<option value="hn">河南省</option>
<option value="sd">山东省</option>
<option value="sx">山西省</option>
</select>
</body>
</html>

9.7 显示网页时钟

JS有一个内置的日期类:Date,可以用来获取时间。常用方法如下所示:

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
<!DOCTYPE html>
<html>
<head>
<title>显示网页时钟</title>
</head>
<body>
<script type="text/javascript">

// 获取系统当前时间
var nowTime = new Date();

// 以文本形式将内容输出到网页上,不是以弹窗的形式
document.write(nowTime);

document.write("<br>");

// 转换成本地格式
document.write(nowTime.toLocaleString());

document.write("<br>"); // 可以编译文本内容

var year = nowTime.getFullYear();
var month = nowTime.getMonth() + 1; // 月份是 0-11
// var dayOfWeek = nowTime.getDay(); // 一周的第几天 0-6
var day = nowTime.getDate(); // 月份的第几天
document.write(year + "年" + month + "月" + day + "日");

document.write("<br>");

// 获取毫秒数
var times = nowTime.getTime();
document.write(times);

</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
<script type="text/javascript">

function displayTime(){
var timeSpan = document.getElementById("timeSpan");
timeSpan.innerText = (new Date()).toLocaleString();

}

var v;

function start(){
// 周期函数,每隔1000毫秒调用 displayTime()函数。返回的参数可以用来终止这个函数的执行
v = window.setInterval("displayTime()", 1000);
}

function stop(){
// 点击按钮,终止时间变化
window.clearInterval(v);
}

</script>

<br>
<input type="button" id="timeBtn" value="显示系统当前时间" onclick="start()"><input type="button" id="timeBtn" value="停止时间" onclick="stop()"><br>
<span id="timeSpan"></span>

9.8 内置支持类Array

简单例子如下所示:

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
<!DOCTYPE html>
<html>
<head>
<title>内置支持类Array</title>
</head>
<body>
<script type="text/javascript">
var arr1 = [];
alert(arr1.length);

var arr2 = [1, 2, 3, false, "asdf", 3.14];
alert(arr2.length);

var strs = arr2.join("-");
alert(strs);

// 在数组末尾添加元素
arr2.push(1);

// 将数组末尾元素弹出
var s = arr2.pop();

// 数组元素反转
arr2.reverse();

// 自动扩容
arr2[10] = "asdfqwer";
alert(arr2.length);

for(var i in arr2){
document.write("<br>");
document.write(arr2[i]);
}

var a = new Array();
alert(a.length);

var a2 = new Array(3);
alert(a2.length);

</script>
</body>
</html>

10. BOM编程

前面提到过BOM编程主要是操作浏览器的动作,虽然BOM广义上是包括DOM的,但是这里不再赘述,仅仅描述浏览器的相关操作。

10.1 window.open()和window.close()

在BOM编程中,window对象是顶级对象,代表浏览器窗口,window有open和close方法,可以开启和关闭窗口。注意,打开窗口不仅仅可以打开网址,也可以打开本地的网页。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<input type="button" value="开始百度(新窗口)" onclick="window.open('http://www.baidu.com')">
<input type="button" value="开始百度(当前窗口)" onclick="window.open('http://www.baidu.com', '_self')">
<input type="button" value="开始百度(新窗口)" onclick="window.open('http://www.baidu.com', '_blank')">
<input type="button" value="开始百度(父窗口)" onclick="window.open('http://www.baidu.com', '_parent')">
<input type="button" value="开始百度(顶级窗口)" onclick="window.open('http://www.baidu.com', '_top')">

<input type="button" value="关闭当前窗口" onclick="window.close()">
</body>
</html>

10.2 window.alert()和window.confirm()

alert消息框是为了展示某个信息,而confirm确认框则是为了获得用户的操作(包含确认和取消两个按钮)。简单例子如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<script type="text/javascript">

function del(){
var ok = window.confirm("确认删除数据吗?");
// alert(ok);
if(ok){
alert("数据删除成功");
}else{
alert("您已取消删除数据");
}
}

</script>

<input type="button" value="弹出确认框" onclick="del();">

10.3 windos.history和window.location

history对象用于访问历史页面。有back()回退方法,即返回当前页面的上一个页面;也有go()方法,前进,参数为-1的话,和back方法效果一样,如果参数为1的话,相当于back的撤销。

history简单例子如下所示:

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
<!-- js_test_23.html -->
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
asdfasdfasdfas<br>
<a href="js_test_24.html">24页面</a>
<input type="button" value="前进" onclick="window.history.go(1)">
</body>
</html>


<!-- js_test_24.html -->
<!DOCTYPE html>
<html>
<head>
<title>测试前进和后退</title>
</head>
<body>
哈哈哈<br>
<input type="button" value="后退" onclick="window.history.back()">
<input type="button" value="后退" onclick="window.history.go(-1)">
</body>
</html>

location对象用于对地址栏上的信息进行设置,所以可以手动设置超链接。简单例子如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<!DOCTYPE html>
<html>
<head>
<title>location</title>
</head>
<body>
<script type="text/javascript">
function goBaidu(){
window.location.href = "http://www.baidu.com";
}
</script>
<input type="button" value="百度" onclick="goBaidu();">
</body>
</html>

另外,document对象也有location对象属性,和上面设置一样。

10.4 将当前窗口设置为顶级窗口

iframe标签用于将完整页面嵌套到新的页面。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<!DOCTYPE html>
<html>
<head>
<title>将当前窗口设置为顶级窗口</title>
</head>
<body>
26页面

<script type="text/javascript">
function setTop(){

// window.top表示当前浏览器窗口对应的顶级窗口
// window.self表示当前按钮所在的窗口
if(window.top != window.self){

// 将按钮所在的窗口设置为顶级窗口(其实就是修改浏览器地址)
window.top.location = window.self.location;
}
}
</script>
<input type="button" value="如果当前窗口不是顶级窗口,将当前窗口设置为顶级窗口" onclick="setTop();">
</body>
</html>

11. JSON

JSON的全称是JavaScript Object Notation,JavaScript对象标记,即一种标准的数据交换格式。JSON是一种标准的轻量级的数据交换格式,特点是体积小,已解析。

在实际的开发中有两种使用较多的数据交换格式:JSON和XML,XML提交较大,解析麻烦,但是其优点是语法严谨,通常银行相关的系统之间进行数据交换的话会使用XML。

HTML和XML有一个父亲:SGML(标准通用的标记语言)。HTML主要做页面展示,所以语法松散,很随意。而XML主要做数据存储和数据描述,所以语法相当严格。

这里的数据交换指的是:不同的系统(或者不同的编程语言)将数据信息转换成JSON格式,而另一个系统则再解析JSON数据获得内容。

简单例子如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<!DOCTYPE html>
<html>
<head>
<title>JSON</title>
</head>
<body>

<script type="text/javascript">

// 创建JSON对象,也被称为无类型对象,没有数据类型,都是string。
var studentJson = {
"sno": "110",
"sname": "张三",
"sex": "男"
};

alert(studentJson.sno + "," + studentJson.sname + "," + studentJson.sex);
</script>

</body>
</html>

可以看到JSON和Java中的Map、Python中的字典类似,JSON可以嵌套。

JS中有window.eval()函数,作用是将一段JS代码格式的字符串转换成JS代码,和Python中的eval函数一样。常见的场景是:Java程序发送过来一段JSON字符串(JSON对象外面套了一层双引号),eval函数将其转换成JS代码,也就是JSON对象。简单例子如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<!DOCTYPE html>
<html>
<head>
<title>JSON</title>
</head>
<body>

<script type="text/javascript">

var fromJava = "{\"name\": \"zhangSan\", \"password\": \"1234\"}";

window.eval("var jsonObj = " + fromJava);

alert(jsonObj.name + "," + jsonObj.password);
</script>
</body>
</html>

11.1 JSON

根据JSON数据动态地将数据显示在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
<!DOCTYPE html>
<html>
<head>
<title>动态绘制表格</title>
</head>
<body>
<script type="text/javascript">

// 将JSON数据显示到table中
var data = {
"total": 4,
"emps": [
{"empno": 7369, "ename": "smith", "sal": 800.0},
{"empno": 7370, "ename": "jack", "sal": 900.0},
{"empno": 7371, "ename": "jenny", "sal": 700.0},
{"empno": 7372, "ename": "danny", "sal": 780.0},
]
};

window.onload = function(){
document.getElementById("display").onclick = function(){

// 解析数据并拼接成html文本段。
var html = "";
var emps = data.emps;
for(var i=0; i < emps.length; i++){
html += "<tr align=\"center\">";
html += "<td>" + emps[i].empno + "</td>";
html += "<td>" + emps[i].ename + "</td>";
html += "<td>" + emps[i].sal + "</td>";
html += "</tr>";
}

html += "<td colspan=\"3\" align=\"right\">总记录条数:<span id=\"total\">" + data.total + "</span></td>"

// 将上述拼接成的文本段添加到表格的tbody中。
document.getElementById("empTbody").innerHTML = html;


}
}
</script>

<input type="button" value="显示员工列表信息" id="display"><br>
<h2>员工信息列表</h2><br>

<table border="1px" width="50%">
<tr>
<th>员工编号</th>
<th>员工名字</th>
<th>员工薪资</th>
</tr>
<tbody id="empTbody">

</tbody>
</table>
</body>
</html>

12. 总结

可以看到,JavaScript作为脚本语言,主要是对HTML标签进行动态操作,以及对浏览器窗口的一些操作,概括起来就是BOM编程和DOM编程,主要掌握一些基本的逻辑即可,具体的函数和用法可以现学现用。

目前有几下几种方法可以通过浏览器向服务器发送请求:

  1. 表单form的提交
  2. 超链接
  3. documen.location.href
  4. window.location.href
  5. window.open()
  6. 直接在浏览器地址栏上输入URL,然后回车。

以上所有的请求方式均可以携带数据给服务器,但只有通过表单提交的数据才是动态的,其余的方法提交的数据都是静态写死的。

13. 备注

参考B站《动力节点》。


文章作者: 浮云
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 浮云 !
  目录