JavaScript基础语法
1.简介
JavaScript 是⼀种具有⾯向对象能⼒的、解释型的程序设计语⾔。更具体⼀点,它是基于对象和事件驱动并具有相对安全性的客户端脚本语⾔。它的主要⽬的是,验证发往服务器端的数据、增加 Web 互动、加强⽤户体验度等。
- JavaScript 的组成
ECMAScript定义的只是这⻔语⾔的基础,与Web浏览器没有依赖关系,⽽在基础语法上可以构建更完善的脚本语⾔。JavaScript的运⾏需要⼀定的环境,脱离了环境JavaScript代码是不能运⾏的,JavaScript只能够寄⽣在某个具体的环境中才能够⼯作。JavaScript运⾏环境⼀般都由宿主环境和执⾏期环境共同构成,其中宿主环境是由外壳程序⽣成的,如Web浏览器就是⼀个外壳程序,它提供了 ⼀个可控制浏览器窗⼝的宿主环境。执⾏期环境则由嵌⼊到外壳程序中的JavaScript引擎(或称为JavaScript解释器)⽣成,在这个环境中 JavaScript能够⽣成内置静态对象,初始化执⾏环境等。
Web浏览器⾃定义的DOM组件,以⾯向对象⽅式描述的⽂档模型。DOM定义了表示和修改⽂档所需的对象、这些对象的⾏为和属性以及这些对象之间的关系。DOM对象,是我们⽤传统的⽅法(javascript)获得的对象。DOM属于浏览器,⽽不是JavaScript语⾔规范⾥的规定的核⼼内容。前⾯的DOM是为了操作浏览器中的⽂档,⽽为了控制浏览器的⾏为和操作,浏览器还提供了BOM(浏览器对象模型)。ECMAScript(基础语法)
3.JavaScript的核⼼语法
ECMAScript描述了该语⾔的语法和基本对象
DOM(⽂档对象模型)
⽂档对象模型(DOM)—— 描述了处理⽹⻚内容的⽅法和接⼝
BOM(浏览器对象模型)
浏览器对象模型(BOM)—— 描述了与浏览器进⾏交互的⽅法和接⼝
\4. 基本⽤法
JS需要和HTML⼀起使⽤才有效果,我们可以通过直接或间接的⽅式将JS代码嵌⼊在HTML⻚⾯中。
⾏内JS : 写在标签内部的js代码
内部JS : 定义在script标签内部的js代码
外部JS : 单独的js⽂件,在HTML中通过script标签引⼊
我们可以将JavaScript代码放在html⽂件中任何位置,但是我们⼀般放在⽹⻚的head或者body部分。由于⻚⾯的加载⽅式是从上往下依次加载的,⽽这个对我们放置的js代码运⾏是有影响的。
放在部分,最常⽤的⽅式是在⻚⾯中head部分放置元素,浏览器解析head部分就会执⾏这个代码,然后才解析⻚⾯的其余部分。放在部分,JavaScript代码在⽹⻚读取到该语句的时候就会执⾏。
\5. JavaScript基础语法
1、语句和注释
JavaScript程序的执⾏单位为⾏(line),也就是⼀⾏⼀⾏地执⾏。⼀般情况下,每⼀⾏就是⼀个语句。
语句(statement)是为了完成某种任务⽽进⾏的操作,语句以分号结尾,⼀个分号即表示⼀个语句结束。多个语句可以写在⼀⾏内(不建议这么写代码),但是⼀⾏写多条语句时,语句必须以分号结尾。表达式不需要分号结尾。⼀旦在表达式后⾯添加分号,则JavaScript引擎就将表达式视为语句,这样会产⽣⼀些没有任何意义的语句。
2、 标识符和关键字
标识符就是⼀个名字,⽤来给变量和函数进⾏命名,有特定规则和规范
规则:
由Unicode字⺟、_、$、数字组成、中⽂组成
(1)不能以数字开头
(2)不能是关键字和保留字
(3)严格区分⼤⼩写
规范:
(1)⻅名知意
(2)驼峰命名或下划线规则
关键字也称保留字,是被JavaScript征⽤来有特殊含义的单词
\6. 变量
变量即⼀个带名字的⽤来存储数据的内存空间,数据可以存储到变量中,也可以从变量中取出数据。
\1. 变量的声明
JavaScript是⼀种弱类型语⾔,在声明变量时不需要指明数据类型,直接⽤var修饰符进⾏声明。
\2. 变量的注意点
(1)若只声明⽽没有赋值,则该变量的值为undefined。
(2)变量要有定义才能使⽤,若变量未声明就使⽤,JavaScript会报错,告诉你变量未定义。
(3)可以在同⼀条var命令中声明多个变量。
(4)若使⽤var重新声明⼀个已经存在的变量,是⽆效的。
(5)若使⽤var重新声明⼀个已经存在的变量且赋值,则会覆盖掉前⾯的值
(6)JavaScript是⼀种动态类型、弱类型语⾔,也就是说,变量的类型没有限制,可以赋予各种类型的值。
3.数据类型
虽说JS是弱类型语⾔,变量没有类型,但数据本身是有类型的。针对不同的类型,我们可以进⾏不同的操作。
JavaScript 中有6 种数据类型,其中有五种简单的数据类型:Undefined、Null、布尔、数值和字符串。⼀种复杂数据类型Object。
当声明了⼀个变量⽽没有初始化时,这个变量的值就是undefined
数 值(Number): 整数和⼩数(⽐如 1 和 3.14)
字符串(String): 字符组成的⽂本(⽐如"Hello World")
布尔值(Boolean):true(真)和 false(假)两个特定值
Undefined: 表示“未定义”或不存在,即此处⽬前没有任何值
Null: 表示空缺,即此处应该有⼀个值,但⽬前为空
对象(object)(引⽤) : 各种值组成的集合
1)、对象(object){name:”zhangsan”,age:”18”}
2)、数组(array)[1,2,3]
3)、函数(function)function test() {}
(2)调⽤函数时,该函数有形参,但未提供实参,则该参数为undefined。 (3)函数没有返回值时,默认返回 undefined。 3.4.2. null
null类型是只有⼀个值的数据类型,即特殊的值null。它表示空值,即该处的值现在为空,它表示⼀
个空对象引⽤。
使⽤Null类型值时注意以下⼏点:
1)使⽤typeof操作符测试null返回object字符串。
2)undefined派⽣⾃null,所以等值⽐较返回值是true。未初始化的变量和赋值为null的变量相
等。
3.4.3. 布尔类型
布尔类型有两个值:true、false。常⽤来做判断和循环的条件
3.4.4. 数值型
数值型包含两种数值:整型和浮点型。
1)所有数字(整型和浮点型)都是以 64 位浮点数形式储存。所以,JS中1 与 1.0 相等,⽽且 1 加上
1.0 得到的还是⼀个整数。浮点数最⾼精度是17位⼩数,由于浮点数运算时可能不精确,尽量不要使⽤
浮点数做判断。
2)在存储数值型数据时⾃动将可以转换为整型的浮点数值转为整型。
function noData(str) { js函数形参只需要变量名即可
console.log(str); undefined
}
noData(); 调⽤⽅法时,未传递参数
⽅法没有返回值
function noData() {
console.log(“Hello”);
}
var re = noData(); 定义变量接收⽆返回值的⽅法
console.log(re);
console.log(undefined == null);
var box = null; 赋值为null的变量
var a; 未初始化的变量
console.log(a == box); 两个的值相等
3.4.5. 字符串
使⽤ ’ ’ 或 " "引起来,如:‘hello’,“good”。
使⽤加号 ‘+’ 进⾏字符串的拼接,如:console.log(‘hello’ + ’ everybody’);
3.4.6. 对象
对象是⼀组数据和功能的集合。
说明:
{}:表示使⽤对象字⾯量⽅式定义的对象。空的⼤括号表示定义包含默认属性和⽅法的对象。
3.5. 类型转换
3.5.1. ⾃动类型转换
console.log(1 == 1.0); true
console.log(1 + 1.0); 2
var num = 8.0; ⾃动将可以转换为整型的浮点数转为整型
console.log(num); 8
3.5.2. 函数转换(String to Number)
JS 提供了 parseInt()和 parseFloat()两个全局转换函数。前者把值转换成整数,后者把值转换成浮
点数。只有对 String 类型调⽤这些⽅法,这两个函数才能正确运⾏;对其他类型返回的都是 NaN(Not
a Number)。 3.5.2.1. parseInt()
在转换之前,⾸先会分析该字符串,判断位置为0处的字符,判断它是否是个有效数字,如果不是,
则直接返回NaN,不再继续,如果是则继续,直到找到⾮字符
3.5.2.2. parseFloat()
该⽅法与 parseInt() ⽅法的处理⽅式相似,从位置 0 开始查看每个字符,直到找到第⼀个⾮有效的字
符为⽌,然后把该字 符之前的字符串转换成数字。不过,对于这个⽅法来说,第⼀个出现的⼩数点是有
效字符。如果有两个⼩数点,第⼆个⼩数点将被看作⽆效的,parseFloat()⽅法会把这个⼩数点之前的
字符串转换成数字。
3.5.3. 显示转换
⼏乎每个数对象都提供了toString()函数将内容转换为字符串形式,其中Number提供的toString()函数可以将数字转换为字符串。
Number还提供了toFixed()函数将根据⼩数点后指定位数将数字转为字符串,四舍五⼊
parseInt(“1234blue”); returns 1234
parseInt(“22.5”); returns 22
parseInt(“blue”); returns NaN
parseFloat(“1234blue”); returns 1234.0
parseFloat(“22.5”); returns 22.5
parseFloat(“22.34.5”); returns 22.34
parseFloat(“blue”); returns NaN
将内容转换为字符串形式
var data = 10
console.log(data.toString())
根据⼩数点后指定位数将数字转为字符串,四舍五⼊
data = 1.4;
console.log(data.toFixed(0));
data = 1.49;
console.log(data.toFixed(1));
不能对null和undefined使⽤
data = null
console.log(data.toString())
data = undefined
console.log(data.toString())
JS 为 Number、Boolean、String 对象提供了构造⽅法,⽤于强制转换其他类型的数据。此时操作的
是整个数据,⽽不是部分。
Number(false) 0
Number(true) 1
Number(undefined) NaN
Number(null) 0
Number( "5.5 ") 5.5
Number( "56 ") 56
Number( "5.6.7 ") NaN
Number(new Object()) NaN
Number(100) 100
Boolean(""); false – empty string
Boolean(“hi”); true – non-empty string
Boolean(100); true – non-zero number
Boolean(null); false - null
Boolean(0); false - zero
Boolean(new Object()); true – object
最后⼀种强制类型转换⽅法 String() 是最简单的,因为它可把任何值转换成字符串。要执⾏这种强制类型转换,只需要调⽤作为参数传递进来的值的 toString() ⽅法,即把 1 转换成"1 ",把 true转换成"true ",把 false 转换成 "false ",依此类推。强制转换成字符串和调⽤ toString() ⽅法的唯⼀不同之处在于,对 null 或 undefined 值强制类型转换可以⽣成字符串⽽不引发错误:
var s1 = String(null); “null”
var oNull = null;
var s2 = oNull.toString(); won’t work, causes anerror
最为简单的⼀种转换为字符串的⽅式,直接在任意数据后⾯ + “” 即可。
运算符 描述 例⼦ 结果
+ 加 x=y+2 x=7
- 减 x=y-2 x=3
* 乘 x=y*2 x=10
/ 除 x=y/2 x=2.5
% 求余数 x=y%2 x=1
++ ⾃增(前导加、后导加) x=++y x=6
– ⾃减(前导减、后导减) x=–y x=4
运算符 例⼦ 等价于 结果
= x=y x=5
+= x+=y x=x+y x=15
-= x-=y x=x-y x=5
= x=y x=x*y x=50
/= x/=y x=x/y x=2
%= x%=y x=x%y x=0
3.6. 运算符
运算符⽤于执⾏程序代码运算,会针对⼀个及其以上操作数来进⾏运算。
3.6.1. 算数运算符
3.6.2. 赋值和扩展运算符
3.6.3. ⽐较运算符
运算符 描述 例⼦
== 等于 x==8 为 false
=== 全等(值和类型) x=5 为 true;x=“5” 为 false
!= 不等于 x!=8 为 true
> ⼤于 x>8 为 false
< ⼩于 x<8 为 true
>= ⼤于或等于 x>=8 为 false
<= ⼩于或等于 x<=8 为 true
运算符 描述 例⼦
&& and (x < 10 && y > 1) 为 true
|| or (x5 || y5) 为 false
! not !(x==y) 为 true
运算符 描述 例⼦
?: 如果…否则… 3>5?3:5
3.6.4. 逻辑运算符
3.6.5. 三⽬运算符
3.7. 控制语句
我们写的 JavaScript 代码都是按照从上到下依次执⾏,很多时候我们希望代码按照我们的意愿去执
⾏,⽐如有选择性地执⾏某些代码,或者重复地执⾏某些代码,这就需要使⽤到流程控制语句。
流程控制语句⼀共有三种:
\1. 流程执⾏:从上到下,从左到右
\2. 选择执⾏:分⽀选择
\3. 循环执⾏:重复执⾏
3.7.1. 选择
3.7.1.1. 单选择
if (条件){
语句体; }
⾸先执⾏条件
如果结果为true,则执⾏语句体;
如果结果为false,则结束if语句。
注意:若语句体只有⼀条语句,可以省略⼤括号,但不建议省略
3.7.1.2. 双选择
⾸先执⾏条件
如果结果为true,则执⾏语句体1;
如果结果为false,则执⾏语句体2。 3.7.1.3. 多选择
3.7.1.4. switch结构
多个 if …else 且值为定值时(即=== 在⽐较运⾏结果时,采⽤的是严格相等运算符(===),⽽不是
相等运算符(==),这意味着⽐较时不会发⽣类型转换。) ,可以使⽤ switch 替换:
if (条件){
语句体1; }else {
语句体2; }
if(⽐较表达式1) {
语句体1; }else if(⽐较表达式2){
语句体2; }else if(⽐较表达式3){
语句体3; }
…
[else {
语句体n+1;
}]
break 防⽌穿透,如果没有 break,则继续执⾏后⾯的代码,直到遇到 break 或全部执⾏完毕,但是有
些时候会利⽤穿透。
3.7.2. 循环
循环结构⽤于重复执⾏某个操作 简单理解就是重复执⾏同类型的代码,它有多种形式。
3.7.2.1. while
先判断后执⾏
3.7.2.2. do…while
先执⾏后判断,⾄少执⾏⼀次
switch(表达式) {
case 值1:
语句体1;
break;
case 值2:
语句体2;
break;
…
default:
语句体n+1;
[break;]
}
基本格式
while(判断条件语句) {
循环体语句;
}
扩展格式:
初始化语句;
while(判断条件语句){
循环体语句;
控制条件语句; 少了它很容易形成死循环
}
3.7.2.3. for
3.7.2.4. 死循环
条件永远成⽴,永远为 true,则会产⽣死循环,下⾯是最简单的死循环
3.7.2.5. break 与 continue
break: 停⽌本层循环
continue:暂停本次循环,继续下⼀次
3.8. 数组
数组是按次序排列的⼀组数据,每个值的位置都有编号(从0开始),整个数组⽤⽅括号表示。
3.8.1. 数组定义
JS 中定义数组的三种⽅式如下(也可先声明再赋值):
3.8.2. 基本操作
基本格式
do {
循环体语句;
}while(判断条件语句);
扩展格式:
初始化语句;
do {
循环体语句;
控制条件语句;
} while(判断条件语句);
for(初始化语句;判断条件语句;控制条件语句){
循环体语句; }
while(true){}
for(;😉{}
var arr = [值1,值2,值3]; 隐式创建
var arr = new Array(值1,值2,值3); 直接实例化
var arr = new Array(size); 创建数组并指定⻓度
数组的⻓度可以通过length属性来获取,并可以任意更改
数组中的每⼀个元素都可以被访问和修改,甚⾄是不存在的元素,⽆所谓越界
3.8.3. 数组遍历
数组的遍历即依次访问数组的每⼀个元素 ,JS提供三种遍历数组的⽅式:
3.8.3.1. 普通的for循环遍历
3.8.3.2. for … in
3.8.3.3. forEach
3.8.3.4. 了解
数组名.length
数组名.length = 新⻓度
数组名[下标]
数组名[下标] = 新值
for(var i=0; i<=数组.length-1; i++){
}
如:
for(var idx=0;idx<arr.length;idx++){
console.log(arr[idx]);
}
for(var 下标(名称任意) in 数组名){
数组名[下标]是获取元素
} 下标(名称任意)
如:
for(var idx in arr){
console.log(arr[idx]);
}
数组名.forEach(function(element,index){
element(名称任意):元素,index(名称任意):下标
})
如:
arr.forEach(function(elem,idx){
console.log(idx + “–>” + elem);
});
数组在使⽤的时候建议⼤家规矩来⽤。在存放数据时,从下标0开始顺序的存放数组元素。
3.8.4. 数组提供的操作⽅法
Array对象为我们提供了⼀些⽅法,可以很⽅便地操作数组
如果下标:
1.为⾮负整数(包括整数字符串):⾃动从0开始,不存在添加 undefined
2.为负数、⼩数、⾮数字符串:这些内容不计算在⻓度内,当成"属性"处理,相当于⾃定义属性。
数组⾮常灵活,使⽤数组元素
1.下标: ⾮负整数(包括整数字符串):
数组.下标
数组[下标]
2.下标:负数、⼩数、⾮数字字符串:
数组[属性]
* for --> 不遍历属性
* foreach -->不遍历属性和索引中的undefined
* for in -->不遍历索引中的undefined
push 添加元素到最后
unshift 添加元素到最前
pop 删除最后⼀项
shift 删除第⼀项
reverse 数组翻转
join 数组转成字符串
indexOf 数组元素索引
slice 截取(切⽚)数组,原数组不发⽣变化
splice 剪接数组,原数组变化,可以实现前后删除效果
concat 数组合并
3.9. 函数
函数,即⽅法。就是⼀段预先设置的功能代码块,可以反复调⽤,根据输⼊参数的不同,返回不同的
值。函数也是对象。
3.9.1. 函数的定义
有三种函数定义的⽅式:函数声明语句、函数定义表达式、Function构造函数
3.9.1.1. 函数声明语句
该种⽅式定义的函数具有声明提升的效果
3.9.1.2. 函数定义表达式
以表达式⽅式定义的函数,函数的名称是可以不需要的
3.9.1.3. Function构造函数
Function构造函数接收任意数量的参数,但最后⼀个参数始终都被看成是函数体,⽽前⾯的参数则列举出了新函数的参数。注意:
-
js中的函数没有重载,同名的函数,会被后⾯的函数覆盖。
-
js中允许有不定数⽬的参数,后⾯介绍arguments对象
3.9.2. 函数的参数、调⽤和return语句
3.9.2.1. 参数
函数运⾏的时候,有时需要提供外部数据,不同的外部数据会得到不同的结果,这种外部数据就叫参数,定义时的参数称为形参,调⽤时的参数称为实参
实参可以省略,那么对应形参为undefined
若函数形参同名(⼀般不会这么⼲):在使⽤时以最后⼀个值为准。
可以给参数默认值:当参数为特殊值时,可以赋予默认值。
参数为值传递,传递副本 ;引⽤传递时传递地址,操作的是同⼀个对象。
var 变量名 = function ([参数列表]) {
}
3.9.2.2. 函数的调⽤
- 常⽤调⽤⽅式
存在返回值可以变量接收,若接收⽆返回值函数则为undefined。
若函数形参同名(⼀般不会这么⼲):在使⽤时以最后⼀个值为准
-
函数调⽤模式
-
⽅法调⽤模式
3.9.2.3. return
函数的执⾏可能会有返回值,需要使⽤return语句将结果返回。return 语句不是必需的,如果没有的
话,该函数就不返回任何值,或者说返回 undefined。
作⽤:
-
在没有返回值的⽅法中,⽤来结束⽅法。
-
有返回值的⽅法中,⼀个是⽤来结束⽅法,⼀个是将值带给调⽤者。
3.9.3. 函数的作⽤域
函数作⽤域:全局 (global variable) 和 局部 (local variable)
-
全局变量与局部变量同名问题
-
在函数中定义变量时,若没有加var关键字,使⽤之后⾃动变为全局变量
3.10. 内置对象
3.10.1. String
3.10.2. Math
3.10.3. Date
Arguments 只在函数内部定义,保存了函数的实参
Array 数组对象
Date ⽇期对象,⽤来创建和获取⽇期
Math 数学对象
String 字符串对象,提供对字符串的⼀系列操作
◦ charAt(idx) 返回指定位置处的字符
◦ indexOf(Chr) 返回指定⼦字符串的位置,从左到右。找不到返回-1 ◦ substr(m,n) 返回给定字符串中从m位置开始,取n个字符,如果参数n省略,则意味着取到字符串末尾。
◦ substring(m,n) 返回给定字符串中从m位置开始,到n位置结束,如果参数n省略,则意味着取到字符串末尾。
◦ toLowerCase() 将字符串中的字符全部转化成⼩写。
◦ toUpperCase() 将字符串中的字符全部转化成⼤写。
◦ length 属性,不是⽅法,返回字符串的⻓度。
◦ Math.random() 随机数
◦ Math.ceil() 向上取整,⼤于最⼤整数
◦ Math.floor() 向⼩取整,⼩于最⼩整数String
获取⽇期
◦ getFullYear() 年 ◦ getMonth() ⽉ ◦ getDate() ⽇ ◦ getHours() 时 ◦ getMinutes() 分 ◦ getSeconds() 秒
设置⽇期
◦ setYear()
◦ setMonth()
说明:
\1. getMonth():得到的值:011(1⽉12⽉)
\2. setMonth():设置值时0~11
\3. toLocaleString():可根据本地时间把 Date 对象转换为字符串,并返回结果。
3.11. 对象
对象(object)是 JavaScript 的核⼼概念,也是最重要的数据类型。JavaScript 的所有数据都可以被
视为对象。JavaScript 提供多个内建对象,⽐如 String、Date、Array 等等。对象是带有属性和⽅法的
特殊数据类型。
简单说,所谓对象,就是⼀种⽆序的数据集合,由若⼲个“键值对”(key-value)构成。通过
JavaScript我们可以创建⾃⼰的对象。 JavaScript对象满⾜的这种”键值对”的格式我们称为JSON格式,以
后会⻅得⾮常多,即伟⼤的JSON对象。
{键:值, 键2:值2,…}
3.11.1. 对象的创建
JS 创建⾃定义对象,主要通过三种⽅式:字⾯量形式创建对象、通过new Object对象创建 、通过
Object对象的create⽅法创建对象。
3.11.1.1. 字⾯量形式创建
◦ setDate()
◦ setHours()
◦ setMinutes()
◦ setSeconds()
◦ toLoacaleString() 转换成本地时间字符串
3.11.1.2. 通过new Object创建
3.11.1.3. 通过Object对象的create⽅法创建
3.11.2. 对象的序列化和反序列化
序列化即将JS对象序列化为字符串,反序列化即将字符串反序列化为JS对象。JS中通过调⽤JSON⽅
法,可以将对象序列化成字符串,也可以将字符串反序列化成对象 。
序列化对象,将对象转为字符串
JSON.stringify(object);
反序列化,将⼀个Json字符串转换为对象。
JSON.parse(jsonStr);
3.11.3. this
this是JavaScript语⾔的⼀个关键字。
它代表函数运⾏时,⾃动⽣成的⼀个内部对象,只能在函数内部使⽤。
随着函数使⽤场合的不同,this的值会发⽣变化。但是有⼀个总的原则,那就是this指的是,调⽤函数的那个对象。
3.11.3.1. 在函数中使⽤this
在函数中使⽤this属于全局性调⽤,代表全局对象,通过window对象来访问。
3.11.3.2. 在对象中使⽤this
在对象中的函数使⽤this,代表当前的上级对象。
JS事件、DOM对象
- 事件
事件 (Event) 是 JavaScript 应⽤跳动的⼼脏 ,进⾏交互,使⽹⻚动起来。当我们与浏览器中 Web ⻚⾯进⾏某些类型的交互时,事件就发⽣了。事件可能是⽤户在某些内容上的点击、⿏标经过某个特定元素或按下键盘上的某些按键。事件还可能是 Web 浏览器中发⽣的事情,⽐如说某个 Web ⻚⾯加载完成,或者是⽤户滚动窗⼝或改变窗⼝⼤⼩。
通过使⽤ JavaScript ,你可以监听特定事件的发⽣,并规定让某些事件发⽣以对这些事件做出响应。
\2. 作⽤
(1)验证⽤户输⼊的数据。
(2)增加⻚⾯的动感效果。
(3)增强⽤户的体验度
\3. 事件中的⼏个名词
例如
事件源: 谁触发的事件
事件名: 触发了什么事件
事件监听: 谁管这个事情,谁监视?
事件处理:发⽣了怎么办
当我们⽤户在⻚⾯中进⾏的点击动作,⿏标移动的动作,⽹⻚⻚⾯加载完成的动作等,都可以称之为事件名称,即:click、mousemove、load 等都是事件名称,具体的执⾏代码处理,响应某个事件的函数。
2.3. 事件类型
JavaScript可以处理的事件类型为:⿏标事件、键盘事件、HTML事件。
Window 事件属性:针对 window 对象触发的事件(应⽤到 标签)
Form 事件:由 HTML 表单内的动作触发的事件(应⽤到⼏乎所有 HTML 元素,但最常⽤在 form 元素中)
Keyboard 事件 : 键盘事件
Mouse 事件:由⿏标或类似⽤户动作触发的事件
Media 事件:由媒介(⽐如视频、图像和⾳频)触发的事件(适⽤于所有 HTML 元素,但
⼏个常⽤的事件:
onclick 、onblur 、onfocus 、onload 、onchange
onmouseover、onmouseout、onkeyup、onkeydown
onfocus:元素获得焦点
onclick:⿏标点击某个对象
onchange:⽤户改变域的内容
onmouseover:⿏标移动到某个元素上
onmouseout:⿏标从某个元素上离开
onkeyup:某个键盘的键被松开
onkeydown:某个键盘的键被按下
onload:当⻚⾯或图像加载完后⽴即触发
onblur:元素失去焦点
元素,那么这个click事件会按照如下顺序传播:
2.4. 事件流和事件模型
我们的事件最后都有⼀个特定的事件源,暂且将事件源看做是HTML的某个元素,那么当⼀个HTML元素产⽣⼀个事件时,该事件会在元素节点与根节点之间按特定的顺序传播,路径所经过的节点都会受到该事件,这个传播过程称为DOM事件流。
事件顺序有两种类型:事件捕获 和 事件冒泡。
冒泡和捕获其实都是事件流的不同表现,这两者的产⽣是因为IE和Netscape两个⼤公司完全不同的事件流概念产⽣的。(事件流:是指⻚⾯接受事件的顺序)IE的事件流是事件冒泡,Netscape的事件流是事件捕获流。
2.4.1. 事件冒泡
IE的事件流叫做事件冒泡,即事件开始时由最具体的元素接受,然后逐级向上传播到较为不具体的节点(⽂档)。
也就是说,click事件⾸先在div元素上发⽣,⽽这个元素就是我们单击的元素。然后,click事件沿DOM树向上传播,在每⼀级节点上都会发⽣,直到传播到document对象。
所有现代浏览器都⽀持事件冒泡,但在具体实现上还是有⼀些差别。
2.4.2. 事件捕获
Netscape提出的另⼀种事件流叫做事件捕获,事件捕获的思想是不太具体的节点应该更早接收到事件,⽽最具体的节点应该最后接收到事件。事件捕获的⽤意在于在事件到达预定⽬标之前捕获它。
1、document
2、在事件捕获过程中,document对象⾸先接收到click事件,然后沿DOM树依次向下,⼀直传播到事件的实际⽬标,即虽然事件捕获是Netscape唯⼀⽀持的事件流模式,但很多主流浏览器⽬前也都⽀持这种事件流模型。尽管“DOM2级事件”规范要求事件应该从document对象开始时传播,但这些浏览器都是从window对象开始捕获的。
2.4.3. DOM 事件流
“DOM2级事件”规定的事件流包括三个阶段:事件捕获阶段、处于⽬标阶段和事件冒泡阶段。⾸先发⽣的是事件捕获阶段,为截获事件提供了机会。然后是实际的⽬标接收到事件。最后⼀个阶段是冒泡阶段,可以在这个阶段对事件做出响应。
2.5. 事件处理程序
事件就是⽤户或浏览器⾃身执⾏的某种动作。例如click、load和mouseover都是事件的名字,⽽响应某个事件的函数就叫做事件处理程序(或事件侦听器)。事件处理程序的名字以“on”开头,因此click事件的事件处理程序就是onclick,为事件指定处理程序的⽅式有好⼏种。
2.5.1. HTML 事件处理程序
某个元素⽀持的每种事件,都可以⽤⼀个与相应事件处理程序同名的HTML特性来指定。这个特性的值应该是能够执⾏的JavaScript代码:
这样做有⼀些缺点,例如耦合度过⾼,还可能存在时差问题(当⽤户点击按钮时,处理函数还未加载到,此时处理函数是单独写的⼀段js代码),⽽且在不同的浏览器上可能会有不同的效果。
2.5.2. DOM0 级事件处理程序
通过JavaScript指定事件处理程序的传统⽅式,就是将⼀个函数赋值给⼀个事件处理程序属性。这种⽅式被所有现代浏览器所⽀持。这种⽅式⾸先必须取得⼀个要操作的对象的引⽤,每个元素都有⾃⼰的事件处理程序属性,这些属性通常全都⼩写,例如onclick,然后将这种属性的值设为⼀个函数,就可以指定事件处理程序了。例如:
以这种⽅式添加的事件处理程序会在事件流的冒泡阶段被处理。⽽且,只能为同⼀个元素的同⼀个事
件设定⼀个处理程序(覆盖),也可以通过删除DOM0级⽅法指定的事件处理程序,只要将属性值设为null即可:
2.5.3. DOM2 级事件处理程序
“DOM2级事件”定义了两个⽅法,⽤于处理指定和删除事件处理程序的操作:addEventListener()和removeEventListener()。所有DOM节点都包含这两个⽅法,并且他们都接受3个参数:要处理的事件名、作为事件处理程序的函数和⼀个布尔值。最后这个布尔值参数如果是true,则表示在捕获阶段调⽤事件处理程序;如果是false则表示在冒泡阶段调⽤事件处理程序。
这种⽅式可以为同⼀个元素的同⼀个事件添加多个处理函数。还可删除事件处理函数,注意,在删除的时候,不能删除匿名处理函数。