JavaScript

JavaScript使网页可以呈现动态效果。

要使用独立的JS文件,必须在要使用该js的html中做一个import的动作。比如我们创建好了myJS.js,在某html文件中import它:

1
2
3
<script src="myJS.js">

</script>

1. 一些要注意的点

  1. js中字符和字符串统称为string类型,且单双引号均可。

  2. js中整数和小数统称为number类型

  3. js中所有变量在赋值之前的值都是undefined,可以把它理解成一个空箱子,我们可以往里面放东西。

    如果主动把某个变量赋值为null,它就变成了一块石头,即指向了不存在的内存地址,我们不能往里存数据,也不能从里面取数据。

    如果某个变量的值为**NaN(not a number)**,代表该数字非法。

    如果某个变量的值为Infinity,表示该变量无穷大

    值为null的变量在javascript中类型为Object,值为undefined的变量类型为undefined,值为NaN的变量类型依然为number,值为Infinity的变量类型为number

  4. 局部块内未加var或者let声明的变量为全局变量(要注意的是,只有当局部块中该代码执行后才能用该变量)

2. DOM

Document Object Model。

Js无法直接操作html标签,但是可以通过操作DOM对象间接的操作html标签,这种关系就像java无法直接操作数据表文件,但是可以通过操作数据库对象来间接的操作数据表文件。

浏览器从web服务器请求到的html页面是被拆分成标签,以二进制流的形式传输过来的,浏览器每接收到一个标签,就会为这个标签生成一个对应的DOM对象(即一个html标签对应一个DOM对象),直到接收完完整的html页面,浏览器这边接收到的所有DOM对象会以树型结构缓存(因为标签之间存在包含关系,所以用树形结构存储),只要浏览器不关闭这个html页面,这个html页面的所有DOM对象就会一直存在浏览器缓存中,一旦关闭,该页面所有DOM对象立即被销毁。

浏览器按照html源码文件从上到下顺序解析

2.1 document对象

浏览器缓存了某个html页面的DOM树后,会生成一个document对象来管理这颗树,它可以定位这颗树上的任意一个DOM节点。当本html页面关闭时,document对象也会随着DOM节点被销毁而销毁。

通过document获取DOM对象的三种方法:

1
2
3
document.getElementById(); //通过id获取
document.getElementsByName(); //通过name获取
document.getElementsByTagName("p"); //通过标签类型获取,比如<p> </p>标签

2.2 对DOM对象进行操作

【获取DOM对象的value】

var val = document.getElementById("one").value;

【改变样式】

document.getElementById("one").style.backgroundColor = 'yellow'

document.getElementById("one").style.resize = "both";

【改变状态属性】

document.getElementById("one").checked = true;

【改变文字显示内容】

注意文字显示内容是指双目标签之间的内容,比如<p> text </p>

document.getElementById("one").innerText = ‘new_text’

或者document.getElementById("one").innerHTML = 'new_text'

区别在于innerText只能接收字符串,innerHTML可以接收字符串和html标签

【调用内置方法】

让光标聚焦到id=11的标签上:document.getElementById("11").focus();

3. JS监听事件

用户在何时以何种方式对标签进行了操作,如果满足监听事件触发条件,就会触发并调用对应函数。

  1. onclick:用户用鼠标单击标签
  2. onmouseover:用户鼠标指针进入标签范围
  3. onmouseout:用户鼠标指针离开标签范围
  4. onfocus:光标聚焦到该标签(一般都是text类的标签)
  5. onblur:光标从该标签失去聚焦
  6. onkeydown, onkeyup, onkeypress:用户按下键盘按键
  7. onload:某网页将服务器发送的所有dom对象加载完毕后触发。该方法很重要,实例看下一小节

4. 将标签与监听事件绑定

有时一个监听事件要对应同一类型的多个标签,那么每一个标签上都要重复写比如onclick(…)这段语句,很麻烦且不方便维护,下面来解决这个问题。

在JS中可以直接给单个dom对象绑定监听事件,格式为:domObject.监听事件 = 处理函数名注意函数名后不能有括号

比如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<script>
function Myfunc(){
...
}

var domObject = document.getElementById("1");
domObject.onclick = MyFunc; //这里函数名一定不能带括号
</script>

//上面两句合起来就相当于下面这句,区别只在于上面两句是javascript代码下面是html标签。
<input type="button" id="1" onclick="MyFunc()"> //注意次MyFunc()必须带括号

//不过既然可以将在html标签上干的活转为javascript,那从灵活,代码复用,可拓展性来看,大多数情况下肯定选择用javascript来干

JS中可以获取一组DOM对象(getElements

1
2
3
document.getElementsByClassName();
document.getElementsByName();
document.getElementsByTagName();

因此我们可以在JS中获取一组对象,然后遍历其中所有对象的过程中一一给它们绑定监听事件,这样就不用我们在html标签中一个个写onclick="MyFunc()"了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function Blue(){
document.getElementById("one").style.backgroundColor = "blue";
}
function Red(){
document.getElementById("one").style.backgroundColor = "red";
}

//获取所有input标签DOM对象,给它们绑定监听事件
function Main(){
var domArr = document.getElementsByTagName("input");
for(var i = 0;i<domArr.length;i++){
domArr[i].onmouseover = Blue;
domArr[i].onmouseout = Red;
}
}

注意Main方法应该在onload时调用,可以将其加在body标签中:

1
2
3
4
5
6
7
8
9
10
<body onload="test()"> //将test方法与onload事件绑定,网页加载完毕立刻调用test()方法。
<script src="myJS.js"></script>

<div id="one" style="background-color: aqua;width: 300px;height: 300px"></div>

a<input type="text"><br>
b<input type="text"><br>
c<input type="text"><br>

</body>

完成后,当我们鼠标悬停到任意一个input标签上时,div块会变蓝,鼠标移开变红。

5. JS函数

function在javascript里面属于一种高级数据类型。

5.1 arguments

1
2
3
4
5
6
7
8
function test(var a){
...
}

//下面这三个调用都是合法的
test();
test(1);
test(1,2);

在JS函数中,形参存在意义仅仅是作为一个助记符,因为向JS函数传递的参数会统统被传到属于该函数的一个arguments数组中,然后才从该数组中取值分配给形参,这时形参也就相当于arguments[0], arguments[1]…

1
2
3
4
5
6
7
8
9
10
11
12
13
function test(){
for(var i = 0; i<arguments.length; i++){
console.log(arguments[i]);
}
}
/*
分别调用
test();
test(1);
test(2,3);
test(4,5,6);
控制台输出1 2 3 4 5 6
*/

5.2 JS函数重载

JS函数重载就是基于arguments数组,用if else自行判断。比如我要函数test当我传字符串时打印字符串,传数字时打印该数字的平方。

1
2
3
4
5
6
7
8
9
10
11
12
13
function test(){
for(var i = 0; i<arguments.length; i++){
var v = arguments[i];
if(typeof v == "string") console.log(v);
else if(typeof v == "number") console.log(v*v);
}
}
/*
分别调用
test(1,2,3); //打印1,4,9
test(4,'aaa'); //打印16,aaa
test("aa","bb",3); //打印 aa,bb,9
*/

5.3 function类型对象

function在JS中是一种数据类型,一个function类型的对象其实就是一个指针,它指向具体函数。

function类型变量有两种声明方式:

  1. function funcName () {…} ——标准形式
  2. var funcName = function () {…}; ——匿名形式

【以标准形式声明的函数,在其声明前就可以被调用】,这是因为浏览器会加载两次script标签,第一次将所有以标准形式声明的函数加载好,第二次忽略这些函数声明,开始自上而下的逐条加载指令。

【以匿名形式声明的函数,在其声明前不可以被调用】,因为浏览器匿名声明函数的语句视为一条普通的指令。

function类型变量(即函数名称)是全局变量

5.4 构造函数

构造函数就是普通函数,是调用方式不同将它们区别开了(有没有new关键字)。

比如声明了函数function func() {...}

那么:func();,或者有返回值时: var v = func();,这是将它作为普通函数调用

如果var v = new func();,这是将它作为构造函数调用,且如果func()有返回值,该值无效。

6. Object类型

JS中所有通过构造函数创建(var obj = new Func())的对象都是Object类型对象,Object类型变量被创建后可【动态地往其中添加/删除属性和方法】。

动态添加属性:obj.fieldName = value 或 obj[fieldName] = value

动态添加函数:obj.funcName = function() {}; 或 obj[funcName] = function() {};

动态移除属性:delete obj.fieldName

动态移除方法:delete obj.funcName

7. JSON

由JSON数据描述格式生成的对象都是Object类型的对象

通过JSON可以在JS中更加方便的生成Object类型对象,例如:

1
2
3
4
5
6
7
var student = {
"sid":1,
"sname":"tom",
"study":function(){
...
}
}

生成一个Object类型对象最简单的一种方式: var obj = {} ,而不用var obj = new Object()

7.1 将java对象转换为JSON字符串

java中的json工具库有几种:谷歌的gson,fastjson速度快但不规范,jackson性能和规范都不错。我们以jackson为例(使用前导入jackson jar包):

1
2
3
4
5
6
7
8
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
People p1 = new People();

ObjectMapper om = new ObjectMapper(); //jackson转换工具
String json = om.writeValueAsString(p1); //将People类型的对象p1转化为json字符串
response.setContentType("application/json;charset=utf-8"); //在响应报文中告知客户端传输的是json类型数据
}

7.2 JS将JSON字符串转化为JSON对象

假定已经接收到JSON字符串data了,调用eval函数可直接将其转化为JSON对象。

1
var jsonObj = eval("(" + data + ")");

后续JQuery有更好的方法,本小节了解即可。