ES
一、基本语法
1.值的分类
引用值分为两种类型:原始值和引用值
1.1原始值 stack栈
Number(数),string“ ”(字符串,用双引号包裹的都是字符串)、Boolean布尔值、undefined(未定义)、null(空值)
1.2引用值 heap堆
2.基本写法
1、语句后面要用分号结束“;”
2、JavaScript语法错误会引发后续代码终止,但不会影响其他代码块
3、书写格式要规范,“= + / -”两边都应该有空格
3.计算操作符
- 基本有:“+” “-” “/” “*” “%摩(一个数除以另外一个数的余值叫魔俗称余数)” ”=””()”
- “=”优先级最弱,“()”优先级最高
- “+” 数学运算、字符串连接,任何数据类型加上字符串都等于字符串
- “++” “–” “+=” “-=” “/=” ”*=” ”%=”
赋值的顺序自右往左,计算的顺序从左往右。 - 注意:=是赋值符号,==是判断是否相等的符号,当“+”两边有一个是字符串,他就会将两边的数据转化成字符串数据,进行连接。
4、弹出块(不常用)
- alert(想要弹出的内容):弹出一个提示框
- confirm确认框:一般是用来消息确认的
二、变量
1、 变量声明
变量的声明、赋值使用var
2、 命名规则
变量名必须以英文字母、_、$开头
变量名可以包含英文字母、_、$、数字
不可以用系统关键字、保留字作为变量名
还没有申请一个变量就使用他就会报错,但是有一种情况是不会报错的,那就是使用typeof属性值。
三、逻辑运算符
在布尔值里面:undefined,null,NaN,“字符串”空串,0,false都属于false。
- &&与:只要有一个错误,他就会停止读取返回错误的赋值,只要都是对的,就会返回最后一个赋值,在工作中做一个中断符
- ||或:与&&刚好相反,遇到真返回,工作中主要是写兼容
(&&遇假停,||遇真停) - !非:自身取反,返回true或者false
四、条件语句
1.if条件判断
If(条件){
执行语句
}
只有条件满足,才会执行条件语句
2.switch条件判断
Switch(里面是条件语句){
Case空格条件:
执行语句;
Case空格条件:
执行语句
Case空格条件:
执行语句;
Break;
}
- 只要满足某个条件的时候,就执行条件所说明的内容,但是及其不负责,只要第一个满足了,后面的不通过判断也会直接执行,所以需要在每个执行语句后方写一个break;
- 要是有很多相同的执行语句,就直接写很多条件判断语句,然后在后面写一个执行语句就可以。
3.break
是用来终止循环,写在执行语句后面。
4.三目运算符
? :
判断条件? 是 : 否 并且返回值
var num = 3 > 2 ? 2 + 3 : 1 + 2;
- 先判断3是否大于2 要是是就执行冒号前面的,要是不是就执行冒号后的
也是先算括号里的东西 再算括号外的 。
五、 for和while循环
1. for循环
运用十分灵活,可以扩展出很多东西
for(var i = 0①;i < 10② ;i++③){
document,write( “a” )
}
先执行一遍①
在判断② 执行语句
在执行一遍③
在判断② 执行语句
在执行一遍③
在判断② 执行语句
在执行一遍③
……
也可以把①和③写在外面
var i = 0①
for(;i < 10 ②;){
document,write( “a” )
i++③
}
也可以这样写
只要for循环的第一个和第三个写在外面,这样就是while循环
2. While循环
只要for循环的第一个和第三个写在外面,就是while循环
while(判断条件){
循环语句
}
3. do while循环
do{
执行语句
} while(条件)
不管是否达成条件 都会先运算一次代码;
4. continue终止循环
终止本次循环,执行下一次循环
5.forin循环
类似于java里面的增强for循环
for(var 遍历名称 in 在那个数组循环[循环索引号])
六、 数组
声明时用[ ]嵌套代表的是数组
1.length数组的长度。
var申请的库名字后加.length代表这个数组的长度
2.确定数组的数据的位置
数组名称[ 要确定的数据的排序]
如: var arr = [1, 2, 3];
arr[0] = 1
注意:数组排序的第一位数是0而不是1,所以你想要确定第一位数的时候就要写数组名称[0]。
3.创造数组(封装 type方法)
两种方法构造函数 一个是系统自带的方法 一个是直接构造数组
- 直接构造数组 :var arr = [ 1,2,3]
- 系统自带的方法 :var arr = new(1,2,3,4) 如果只传了一个参数,那就会默认把那个参数当成数组长度,而不是数组内的值。
4.数组常用方法
-
会改变数组的
- Push:arr.push(增加的量);会在数组的最后一位增加push的量
- Pop:arr.pop(); 会剪切数组的最后一位,可以用一个变量接收。传参没用
- Push和pop是一对反义词
- Unshift:在数组前面加参数
- Shift:在数组前面减
- Splice:arr.aplice(从第几位开始,截取多少位的长度,在接口处添加新的数据)
- Sort:对数组以asc码进行排列,arr.sort(方法),括号里是填写方法
- 1.必须写两个形参
- 2.看返回值
- 1)当返回值是负数的时候,那么前面的书放在前面
- 2)当返回值是正数的时候,那么后面的数字放在前面
- 3)为0,不动
也可以直接简化成Arr.sort(function(a, b){ If(a > b){ Return 1;}else{ Return -1; })这是全部代码
var arr = [1,2,3,4,5,6,7]; arr.sort(function (a, b) { return a - b; 升序 return b – a; 降序 })
-
不会改变数组的
- Concat:将两个数组拼接在一个 arr.concat(arr1) 它会将两个数组拼接在一起,并且不会改变原数组,可以重新var一个来接收他
- Slice:arr.slice(从第多少位开始截取,截取到多少位),不会改变原数组,也可以重新var一个来接收他;只有一个参数就是从第几位开始,一直截取到最后;一个参数都不写就是整个截取
- Join:arr.join(“”)里面一定要传字符串类型的,它会将数组里的每一位都以字符串里的东西连接在一起,并返回一个字符串,啥都不穿就是以逗号来连接 。
- Split:与join可逆,讲字符串以什么拆分为数组
5.类数组
是对象,但是可以当数组用,这就叫类数组
- 类数组的要求:要以索引(数字)为属性,必须有length属性,最好有push方法,这样看起来还是数组,也可以加split方法看起来像对象
var leishuzu = {
"0" : "a",
"1" : "b",
"2" : "c",
"length" : 3,
"push" : Array.prototype.push,
"splice" : Array.prototype.splice
}
七、 对象
书写方法
Var 名字 = {
一 :类型(number,string等等 也可以是函数等等),
二 :类型 ,
三 :类型 ,
四 :类型 (最后一个不用写 , )
}
可以理解为另外一种数组
在数组里选中自己的某一个属性 ,有两种写法,一种是对象名.属性
一种是this.属性
1.选中对象中的项
先输入数组名称,然后用.隔开,然后在输入要选中的项的名称。
2.增,删,改,查
①增:直接在控制台(不仅仅只能书写在控制台,书写在控制台只是方便查看,与书写在代码行的最下方是一个道理)上写 名字.要增加的属性 = 要给属性赋值的值
②查:直接在控制台上写 名字.要查看的属性
③改:直接书写 名字.要修改的属性 = 要修改的值
④删: delete 名字.要删除的属性
3.对象的创建方法
① var obj = {}
② 构造函数
- A)系统自带的构造函数 object()
- 书写方法:
先创建一个函数
var 数组名字 = new 函数名 ()
只要系统读到new 函数名的代码,系统自动会在函数内部var this = {} 数组,然后将函数内部的项放在数组里面,然后最后有一个隐式的返回值return this。
- 书写方法:
function Car(name, age) {
this.name = name;
this.age = age;
}
new Car('ryx', 17);
```
- B) 自定义
将系统自己定义的this改成自己想改的东西,然后系统隐式书写要自己加上去。
```javascript
function Car(name,age) {
var that ={};
that.name =name;
that.age = age;
return that;
}
var ryx = Car('ryx', 18)
```
### 4.包装类
A) new string
B) new Boolean
C) new number
### 5.构造函数的原型(prototype)
  函数在new的前一刻,他会产生一个函数名.prototype的对象,这里面保存的就是系统自定义的属性,也叫系统原型。
  函数原型是function对象的一个属性,他定义了构造函数创造出的对象的公共祖先。通过该构造函数产生的对象,可以继承该原型的属性和方法。原型也是对象。
```javascript
Obj.prototype 你可以在这里加入项,让它创建一个类似公共类
function Obj(name, age) {
}
var obj = new Obj;
系统除了会创建prototype,还会在隐式第一步创建对象的时候在对象里 自动加入__proto__属性 __proto__里指向的就是prototype,即引用prototype
Obj.prototype{}
function Obj(name, age) {
__proto__ = Obj.prototype
}
var obj = new Obj;
而除了产生__proto__属性外,还会产生一个叫做Obj.constructor的原型,这里面存放的是函数的原型,没有被new的原型
注意预编译环节!!!!!!!!!!!
6.原型链
将prototype进行嵌套
- A)原型链上面的增删改查:
- 删除和增加:只可以通过自己来进行删除,不能通过子孙来删除
- 查看:在控制台查看
- 修改:要是子孙修改,那就直接是自己增加,要是自己修改 才是修改
- B)继承
绝大多数的对象都会继承object.prototype
但是有一个特例,那就是用object.create构造的原型,他继承的是他设置的对象原型。
Demo.prototype{};
function Demo(params) {
}
var obj = new Demo;
var obj1 = ojbect.create(Demo。prototy);
7.call
更改构造函数this的指示方法,借用别人的函数实现自己的功能。
在任何函数执行值后都可以加上.call方法
function one(name, age) {
this.name = name;
this.age = age;
}
var two ={}
one.call(two, 'ren', 17)
这时候括号里的第一位是将this更改为所设定的函数位置,后面则是正常传参。
8.apply
和call用处差不多,但是call需要把实参通过形参的个数一个个传进去,但是apply则需要传一个arguments(实参列表)
Call和apply都是用来改变this指向,传参方法不同
9.共享原型
用原型链方式继承原型,会导致继承很多不必要的原型
共享原型比较常用。
father.prototype.lastName = "lv";
function father(params) {
}
function son(params) {
}
function jicheng(要继承的, 被继承的) {
要继承的.prototype =被继承的.prototype;
}
jicheng(son, father);
var Son = new son();
代码行数书写位置,不能在还没继承之前就new
缺点:当要继承的函数想要在原型上增加一个属性 是增加不了的,要是通过Yaojichengde.prototype.要增加的原型 = ““;来实现 被继承的prototype也会被修改,从而通过修改,有了圣杯模式。
10.圣杯模式
是共享原型的一个小改变,在原型继承过程中增加一个中间层,起到过度环节
father.prototype.lastName = "lv";
function father(params) {
}
function son(params) {
}
function jicheng(要继承的, 被继承的) {
function 中间层(){};
中间层.prototype = 被继承的.prototype;
要继承的.prototype = new 中间层();
要继承的constuctor = 要继承的;
要继承的.prototype.uber(自己构造的一个属性,里面储存的是真正继承谁的prototype) = 被继承的.prototype;
}
jicheng(son, father);
var Son = new son();
圣杯模式高级写法:
var inherit = (function () {
var F = function (){};
return function (要继承的, 被继承的) {
F.prototype = 被继承的.prototype;
要继承的.prototype = new F();
要继承的.prototype.constructor = 要继承的;
要继承的.prototype.user = 被继承的.prototype;
}());
11.遍历,枚举
a).for in循环
for(var prop in 数组名){
console.log(prop + “” + typeof(prop));
}
- 首先var一个叫做prop的数组,然后在数组里循环,数组里有多少个属性名就循环多少次。并且把属性名都放在prop里。 Prop的名字可以自己改。但是这样就算是隐藏属性也会被算入到属性名里,这时候有个方法(hasownprorty(prop)),这个可以判断是否是原型的属性,是原型的属性会被规避。
最正确的书写方法:
for (const key in object) {
if (object.hasOwnProperty(key)) {
}
}
注意:
var ryx ={
jj : 1,
shenggao : 150,
age : 3,
name : 'ljydez'
}
for (const prop in ryx) {
if(ryx.hasOwnProrty(prop)){
console.log(ryx.prop);
}
}
这样写系统会将rxy.prop转换成ryx[‘prop’],这样就是查找出ryx这个数组里的prop属性,但是没有定义,会变成undefined,想要访问数据需要写成
var ryx ={
jj : 1,
shenggao : 150,
age : 3,
name : 'ljydez'
}
for (const prop in ryx) {
if(ryx.hasOwnProrty(prop)){
console.log(ryx.[prop]);
}
}
除了hsaOwnProrty之外,还要一个instanceof(非常重要)
A instanceof B 看A对象的原型链上,有没有B的原型,然后返回true和false
12.this
①函数与编译过程中this——>window
②全局作用域里this——>window
③call/apply 可以改变函数运行时this指向
④obj.fun(); 这里的this指向obj,要是没有obj或者this 那么指的就是window,可以把windows看成是一个大的对象
13.arguments 克隆
浅层克隆
function clone(origin , targent) {
var target = targent || {}; //防止不传参
for (const prop in origin) {
target[prop] = origin[prop];
}
return target;
}
clone(obj, obj1);
很好用,但是这是两个函数指向一个房间,只要改变一个对象数据,就会改变clone的数据
深层克隆
步骤:
遍历对象 for(var prop in obj)
1、判断是不是原始值 typeof() object
2、判断是数据还是对象
三种方法:instanceof 、 constructor 、 tostring(推荐使用)
3、建立相应的数组或对象
4、递归
function dellclone(origin, targent) {
var targent = targent || {},
toStr = Object.prototype.toString,
arrStr = "[Object Array]";
for (const prop in origin) {
if (origin !== "null" && origin.hasOwnProperty(prop)) {
if (typeof(origin[prop]) == 'object') {
if (toStr.call(origin[prop] == arrStr)) {
targent[prop] = [];
}else{
targent[prop] = {};
}
}
dellclone(origin[prop], targent[prop])
}else{
origin[prop] = targent[prop];
}
}
return targent;
}
dellclone(被继承的, 要继承的);
深层克隆的两个数组的值不会相互影响。
14.create
在这里插入代码片先创建一个对象,然后在用create创建一个新对象,create所指向的那个对象就会是新对象的原型,而不是prototype
var yuanxin = {
ryx : '123'
}
var obj = Object.create(yuanxin);
这时候obj 的原型就不是prototype了,而是原型
八、 数据转换
a)显示类型转换
1、区分数据类型
- Typeof属性 他返回的值都是string类型。
使用方法:typeof(数据);
它会自动返回告诉你数据是什么类型的。
可以返回的类型:Number(数),string“ ”(字符串,用双引号包裹的都是字符串)、Boolean布尔值、undefined(未定义)、object(表示一种引用值)、function(函数方法)
2、number
转换成数字类型,在要转换的值前面加number,他会千方百计的转换成数字,null会显示是0,undefined还有字母的字符串会转换成NAN,ture转换成number就是1,false转换成0
3、Parseint
可以在parseint后的括号前面写数据{radix},中间用逗号隔开,后面写进制数(2~32)
代表以目标进制为基底,转换成十进制。
砍断原则,一直读取读取到非数字位即给你砍断。
4、parseFloat
与parseint差不多,但是他会看到除了第一个点以外的非数字位。
5、string
不管什么都会给你转换成字符串。
6、Boolean
按照布尔值的判断规则,返回true和flase
7、tostring
和string差不多,只是其他的是把要转换的数据放在括号后面,而tostring是写在前面
书写方法:数据.tostring()
- 什么都可以,但是有两个不能,一个是undefined,他会报错;一个是null,也会报错。
- 也可以在括号内加入基底,将数据转换成目标进制。还有数字不能直接转换为tostring类型,因为123.toString系统会自动将123后面的·识别为小数点。
8、toFixed
保留几位有效数字
var a = 12.456789;
document.write(a.toFixed(3))
上面代表的是a保留三位小数并且还要四舍五入。
B)隐式类型转换
-
IsNAN()对应的是number : 判断是否是nan的值,按照显示类型number来判断是否是NAN。
-
++ – +/- :只要++或者—一放,便会自动调动显示类型转换的number,直接将数据首先转换成数字类型直接转换。是否转换成数字不清楚,但是一定是数字类型。+/-是正负,不管能不能转换出确定的值,都会强制转换成数字类型的数据。(字符串类型则是转换成NaN)
-
当“+”两边有一个是字符串,他就会将两边的数据转化成字符串数据,进行连接。
-
加减乘除都是一样的,都是先转换成number。
-
>, <, >=, <= : 当进行数据①>②>③比较的时候,会先判断①和②的比较,然后返回true和false,然后将ture和false转换成number,然后在将ture和false转换成的number和③进行比较。
-
NAN啥都不等于,也不等于自己
C)绝对不发生类型转换的符号
绝对等于 ===
绝对不等于 !==
九、 函数
要求:高内聚,弱偶合。
1.函数声明
命名规则第一个字母是小写,要是由多个单词书写,后面的单词首字要大写。
Function 名字(参数){
内容
}
名字(实参);
以上为一个完整的函数。
2.函数的表达方式
- A)命名函数表达式
Var test = function abc(){
Document,write(“a”)
}
- B)匿名函数表达式(常用)
Var test = function (){
Document,write(“a”)
}
直接继承var的名字,方便观看,之后实际应用中也更好维护。所以一般所说的函数表达式都是指匿名函数表达式。
3.arguments实参数列
实参的数组,在JavaScript里面,实参长度与形参长度不匹配也是可以的,实参的所有都会保存在arguments里面,可以使用arguments.length来查看这个实参数组的长度。
-
①length
查看参数组的长度,有多少位参数 -
②callee
绝对等于函数
Function text(){
Console.log(arguments.callee === text)
}
4.实参的一些小规则
实参在后面可以通过赋值进行修改,通过赋值的方法进行修改
实参在出生时有多少位就是多少位,在函数内部加入实参是没有效果的。
5.return终止函数
在函数内部代码位置加入return,即可在此处终止函数。
也可以用做是返回一个数值的意思,在return后面加一个空格然后写要返回的数值。
6.小知识
函数里面的可以引用函数外面的,但是函数外面的不能引用函数里面的。
7.立即执行函数(只是用一次的函数)
针对初始化函数的定义
书写方法: (function (){
}())
先写一对括号,然后在括号里书写一个匿名函数,然后在匿名函数后面书写一个括号,后面的括号就是用来穿实参的
DOM
DOM是object model的简称,它定义了表示和修改文档所需的方法。DOM对象即为宿主对象,由浏览器厂商定义,用来操作html和xml功能的一类对象集合。也有人说DOM是对html以及xml的标准编程接口。
DOM生成成组的东西,基本上全是类数组。
A)节点
类型:
- 元素节点——1
- 属性节点——2
- 文本节点——3
- 注释节点——8
- document——9
- DocumentFragment——11
①查
- 直接查
Document代表整个文档。
document.getElementByid(‘’)选中页面里id名为(‘’)的元素,因为id是一一对应,所以element不需要加s。
document.getElementsByTagName(‘’)[]选中页面里标签名为(‘’)的标签,并且创建一个类数组,[]里选中的是类数组中的第几位。
document.getElementsByName(‘’)选中页面中name是(‘’)的属性,只有部分标签name才可以生效(表单,表单元素,img,iframe)。
document.getElementsByClassName(‘’)选中类名。低于ie9不兼容。
document.querySelector(‘’)css选择器,和css一样使用选择器(静态)
document.querySelectorAll(‘’)css选择器,选出一个组,ie7及以下不兼容(静态) - 遍历节点树(比较没节操)
用尖括号隔开一个节点,两个尖括号中间要是有空格或者文本,也算一个节点。
.parentNode 父级节点
.childNodes 子节点们
.firstChild 第一个子节点
.lastChild 最后一个子节点
.nextSibling 后一个兄弟节点
.previousSibling 前一个兄弟节点 - 遍历元素节点树
真正对元素进行遍历(有节操),但是IE9一下都不兼容
.parentElement 返回当前元素父节点(IE不兼容)
.children 只返回当前元素的元素子节点
.childElementCount 直接等于.children.length当前元素子节点的个数
.firstElementsChild 返回第一个元素子节点
.lastElementsChild 返回最后一个元素子节点
.nextElementSibling 下一个兄弟节点
.previousElemetSibling 上一个兄弟节点
②.四个属性
nodeName 元素标签名,只读
nodeValue Text和Comment节点的文本内容,可读写
nodeType 节点的类型,只读(返回数字)
attributes Element节点属性集合
③.一个方法
Node.hasChildNodes() 如果节点有子节点则返回true ,否则返回false。
④增
document.createElement(‘’); 创建元素节点
document.createTextNode(‘’); 创建文本节点
document.createComment(‘’) 创建注释节点
document.createDocumentFragment
⑤.插
appendChild() 插入一个节点,可以理解成.push,但是当一个页面里已有的东西appendChild()到另外一个地方那就是剪切。
父级.insertBefore(a, b) 在b之前插入a。
⑥删
parent.removeChild() 谋杀,父节点删除子节点,可以接受它。
节点.remove() 自杀,调用方法删掉自己
⑦替换
parent.replaceChild(new, origin) 上镜不高
⑧.Element节点的一些属性
innerHTML 将之前的内容取掉,写入新的属性
innerTEXT 只取写文本内容,标签等都不会取掉。
⑨.节点上的一些方法
element.setAttribute(‘’, ‘’); 加一个属性名和一个属性值,加行内属性
element.getAttribute(‘’); 取出类型值,括号里面加属性名,返回出来的是属性值
B)日期对象
系统提供好了的,只需要new就可以了
var date = new Date();
具体使用方法有很多,直接在w3school上搜索 就可以了
C)定时器
定时非常不准确
setInterval(function(){
},时间单位毫秒); 定时循环器
每隔多少毫秒,就执行一次function里面的函数。
定时器每循环一次就会返回一个数,想要到达设定的数,就需要clearInterval(定时器名或者返回的数字);
setTimeout(function(){
}, 时间单位毫秒); 达到时间循环一次
同样,也有clearTimeout();
两个定时器都是window的方法,里面的this指向window。
D)获取窗口属性
滚动条滚动距离
window.pageXOffset
window.pageYOffset
ie8及以下不兼容
x : document.body.scrollLeft + document.documentElement.scrollLeft,
y : document.body.scrollTop + document.documentElement.scrollTop
上面这两种方法ie8及以下混杂兼容,直接封装一个函数
// 滚动条滚动多少距离
function getScrollOffset() {
if (window.pageXOffset) {
return{
x : window.pageXOffset,
y : window.pageYOffset
}
}else{
return{
x : document.body.scrollLeft + document.documentElement.scrollLeft,
y : document.body.scrollTop + document.documentElement.scrollTop
}
}
}
以上函数要用的时候直接调用
页面可视区域
window.innerWidth/innerHeight
ie8及以下不兼容
document.docuentElement.clientWidth/clientHeight
标准模式下,任意浏览器都兼容
document.body.clientWidth/clientHeight
适用于怪异模式下的浏览器
// 返回可视化页面宽度
function getViewportOffset() {
if (window.innerWidth) {
return {
w : window.innerWidth,
h : window.innerHeight
}
}else{
return{
w : document.documentElement.clientWidth,
h : document.documentElement.clientHeight
}
}
}
查看元素几何属性
查看元素尺寸(视觉上的)
// 已经被getBoindingClientRect()取代
domEle.offsetWidth
domEle.offsetHeight
让滚动条滚动
window上的三种方法
scroll(),scrollTo(), 可以往括号里传两个参数,第一个代表x轴滚动距离,第二个代表y轴滚动距离,他只会滚动到当前距离,不会累加滚动
scrollBy 使用方法和scroll()一样,但是他会累加滚动
利用scrollBy()可以实现快速阅读功能。推荐加个锁
E)脚本化css
任何DOM元素都有style属性,展示的只有行间的样式表 ,可读可写,写入的值要为字符串属性
碰到float这种保留字,需要在前面加上css float变成cssFloat
window.getComputedStyle(element, null)[prop],展示的是所有的(有行间展示行间,没有展示内嵌样式),可读,获取的值都是经过计算的,并且IE9以下不兼容,IE9以下用 element.currentStyle[prop]。封装一个方法
// CSS封装兼容性方法
function getStyle(element, prop) {
if (window.getComputedStyle) {
return window.getComputedStyle(element, null)[prop];
}else{
return element.currentStyle[prop];
}
}
获取伪元素(伪类)的唯一方法
window.getComputedStyle(element, “伪类名称”)
F)事件
事件类型访问网站查看全部类型https://www.w3school.com.cn/jsref/dom_obj_event.asp
绑定事件
绑定事件要是用到for循环里的i,就要注意闭包的问题
- ①句柄方式:用on+事件类型来绑定,兼容性很好,但是只能绑定一个事件,基本等于将事件写在html的行间上,this指本身
- ②W3C方式:element. addEventListener((‘事件类型’, 处理函数 , false))可以多次绑定多个处理函数,函数引用代表的是一个函数,this指本身
- ③IE独有:element.attachEvent(‘on+ 事件类型’, 处理函数),可以多次绑定处理函数,就算是同一个处理函数绑定多次也可以执行多次,this指window。想让这里指向this需要通过中间层 然后call改变this指向
Element.attachEvent('onclick', function () {
handle.call(Element);
})
function handle() {
// 事件处理函数
}
封装一个函数addEvent,给一个DOM对象添加一个该处理事件类型的函数
function addEvent(elem, type, handle) {//elem = DOM元素 type = 事件触发类型 handle = 事件处理函数
if (elem.addEventListener) {
elem.addEventListener(type, handle, false);
}else if(elem.attachEvent){
elem.attachEvent('on' + type, function () {
handle.call(elem);
})
}else{
elem['on' + type] = handle;
}
}
解除事件
- ①句柄模式:elem.onclick = null; 解除事件绑定,想让某个事件只执行一次,就将这个写在里面,并且将elem改成this
- ②W3C方式:elem.removeEventListener(‘onclick’, 函数名, false),想要事件能被删除,就不要用匿名函数,用函数引用
- ③IE:elem.detachEvent(‘on’ + type, 函数名),想要事件能被删除,就不要用匿名函数,用函数引用
事件处理类型
- 只能使用一种处理类型,要么冒泡,要么捕获,将addEventListener后面最后一个false改成true则变成了捕获类型,false是冒泡类型,要是一个元素绑定两个事件,则先捕获后冒泡,事件执行顺序就符合JavaScript的书写顺序
- 事件冒泡(常规模型):结构上(html结构)被嵌套的元素,会存在事件冒泡的功能(自底向上)。
- 事件捕获(IE没有捕获事件):和冒泡相反,由外向内,先执行外面的,在执行内部的事件
- 取消冒泡:
在执行函数里可以传一个形参,并且形成一个对象,在事件触发时会将很多数据记录在里面,而W3C组织规定在执行函数里写上 形参名.stopPropagation(); 则停止冒泡(IE9以下不能用),IE9以下使用 形参名.cancelBubble = ture; 封装一个函数stopBubble,使其停止冒泡,要用的时候直接stopBubble(形参名);
function stopBubble(event) {
if (event.stopPropagation) {
event.stopPropagation();
} else {
Event.cancelBubble = true;
}
}
- 阻止默认事件:
浏览器自带很多默认事件,可以手动进行阻止,也是要通过执行函数的形参来,封装一个函数,阻止默认事件
function cancelHandler(event) {
if (event.preventDefault) {
event.preventDefault();
} else {
event.returnValue = false;
}
}
事件原对象
指的是触发事件的那个对象的原型,他会保存在事件触发的那个执行函数的形参里,通常要有一个兼容
除了ie外都可以直接在执行函数里的参数写e,但是IE不可以,他直接将执行函数里的e储存在window.event上,所以要写个兼容 event || window.event
火狐上看原对象用 target
IE上用 srcEvent
Google上两种都有,但是通常都要有一个兼容
div.addEventListener('click', function (e) {
var event = e || window.event;
var target = event.target || event.srcElement;
}, false)
鼠标事件
click 点击事件=mousedown+mouseup
mousemove 监听鼠标移动
mousedown/mouseup 鼠标点击/松开发生的事件
mouseover/mouseout 当鼠标盖住/离开触发事件
mouseenter/mouseleave IE远古使用的鼠标盖住/离开事件
用.button来区分鼠标的按键 0(left)/1(wheel)/2(right)
DOM3标准规定:click事件只能监听左键,只能用mousedown和mouseup来判断鼠标键
键盘事件
keydown>keypress>keyup 最先出keydown然后keypress
按下 按下 抬起来
keydown和keypress的差距
keydown可以响应任意键盘按键,keypress只可以响应字符类型键盘按键。
keypress返回ASCII码,可以转换成相应字符。
keydown检测字符类案件是不准的,keypress检测的很准(类似区分大小写)
文本操作事件
input.(on+type)
type类型:
input 但凡输入框里内容有变化都会触发input事件
change 对比的是聚焦前后是否发生改变,要是没改变则不会触发。
focus 文本框获得鼠标时的改变
blur 文本框失去鼠标时的改变
窗体类操作事件(window上的事件)
window.(on+type)= function;
scroll 滚动条一滚动scroll事件触发,获取当前位置
load 当所有东西都准备好了才会执行load,尽量不用,影响速度,可以将广告放在里面。
Json
- 一种传输对象的格式,在正常情况下对象的属性名是不用加双引号的,但是Json的属性名要加上双引号。
两种语法让Json在这两个之间转换
JSON.parse(); string->Json
JSON.stringify(); Json->string
- 要传输数据时直接把要传输的对象写在括号里,它便会返回一个字符串