Javascript基础
Javascript输入输出语句
方法 | 说明 | 归属 |
---|
alert(msg) | 浏览器弹出警示框 | 浏览器 | console.log(msg) | 浏览器控制台打印输出信息 | 浏览器 | prompt(info) | 浏览器弹出输出框,用户可以输入 | 浏览器 |
变量
变量的声明
格式:
// 变量声明
var age; //声明一个名称为age的变量
- var是一个JS关键词,用来声明变量,(variable变量的意思)。使用该关键词声明变量后,计算机会自动变量分配内存空间,不需要程序员管
- age是程序员定义的变量名,我们要通过变量名来访问内存中分配的空间
变量初始化
格式:
var age = 18;//声明变量的同时赋值为18
声明一个变量并赋值,我们称之为变量的初始化。
变量语法扩展
更新变量
一个变量更新以后,他原有的值会被覆盖,变量值将以最后一次赋值为准
var age = 18;
age = 81; //最后的结果是81因为18被覆盖了
同时声明多个变量
同时声明多个变量,只需要中间加个,分开即可
格式:
var age = 10,name = ‘zs’,sex = 2;
声明变量的特殊情况
情况 | 说明 | 结果 |
---|
var age;console.log(age) | 只声明 | underfined | console.log(age) | 不声明,不赋值 | 报错 | age = 10.console.log(age) | 不声明,只赋值 | 10 |
变量命名规范
- 由字母(A-Z,a-z)、数字(0-9)、下划线(_)、美元符号($)组成,例如:usrAge、num01,_name
- 严格区分大小写。var age 和 var AGE是两个不一样的变量
- 不能数字开头。18age是错误的
- 不能关键字,保留字。例如var,for,while
- 变量名必须有意义。MMD,BBD,nl–>age
- 遵守驼峰命名法。手写字母小写,后面单词字母需要大写。myFistName
- 推荐翻译网站,有道,爱词霸
数据类型
数据类型分类
- 简单数据类型(Number,string,Boolean,Undefined,Null)
- 复杂数据类型(object)
简单数据类型
简单数据类型 | 说明 | 默认 |
---|
Number | 数字型,包含整型值和浮点型值,如21和0.21 | 0 | Boolean | 布尔值类型,如true,false.等价于和0 | false | String | 字符串类型,如‘张三’ | ‘ ’ | Underfined | var a; 声明了变量a当时没有给值,此时a = underfined | underfined | Null | var a=null; 声明了变量a为空值 | null |
在JS中八进制前面加0,十六进制前面加0x
数字型范围
最大值和最小值:
alert( Number.MAX_VALIUE);//1.7976931348623157e+308
alert(Number.MIN_VALUE); //5e-324
数字型三个特殊值
alert(Infinity); //Infinity
alert(-Infinity); //-Infinity
alert(NaN); //NaN
- Infinity代表无穷大,大于任何数
- -Infinity代表无穷小,小于任何数
- NaN,Not a number,代表个非数值
isNaN
isNaN判断是否为非数字
字符串型
字符创型可以是引号中的任意文本,其语法为双引号“ ”和单引号‘ ’,推荐使用单引号。(外单内双)
字符串转义符
转义符 | 解释说明 |
---|
\n | 换行符 | \\ | 斜杠\ | \’ | '单引号 | \" | "双引号 | \t | tab缩进 | \b | 空格,b是blank的意思 |
布尔型Boolean
布尔类型有两个值:true和false,其中true表示对,而fulse表示错
获取检测变量类型
typeof可用来获取检测变量的数据类型
逻辑运算符
逻辑运算符 | 说明 | 案例 |
---|
&& | 逻辑与,and | true&&false | || | 逻辑或,or | ture||false | ! | 逻辑非,not | !true |
短路运算(逻辑中断)
短路运算的原理:当有多个表达式时,左边的表达式值可以确定结果时,就不再运算右边的表达式的值
1.逻辑与
- 语法:表达式1&&表达式2
- 如果第一个表达式的值为真,则返回表达式2
- 如果第一个表达式的值为假,则返回表达式1
2.逻辑或
- 语法:表达式1||表达式2
- 如果第一个表达式为真,则返回表达式1
- 如果第一个表达式为假,则返回表达式2
运算符优先级
优先级 | 运算符 | 顺序 |
---|
1 | 小括号 | () | 2 | 一元运算符 | ++ – ! | 3 | 算数运算符 | 先* / % 后 + - | 4 | 关系运算符 | > >= < <= | 5 | 相等运算符 | == != === !== | 6 | 逻辑运算符 | 先&&后 || | 7 | 赋值运算符 | = | 8 | 逗号运算符 | , |
- 一元运算符里面的逻辑非优先级很高
- 逻辑与比逻辑或优先级高
if语句
语法结构:
// 条件成立执行代码,否则什么也不做
if(条件表达式){
? //条件成立执行的代码语句
}else if(){
? //执行代码
}else{
? //执行代码
}
三元表达式
三元表达式也能做一些简单的条件选择,有三元运算符组成的式子称为三元表达式
语法结构:
条件表达式?表达式1:表达式2
如果条件表达式结果为真,则返回表达式1,如果条件表达式为假,则返回表达式2
switch语句
语法结构:
switch(表达式){
? case value1:
? 执行语句;
? break;
? case value2:
? 执行语句;
? break;
…
? default:
? 执行语句;
? break;
}
注意:
1.我们开发里面,表达式经常写成变量
2.我们的value和表达式的值要全等的关系才能匹配
3.break如果当前case里面没有break,则不会退出switch,是继续执行下一个case
switch语句和if elseif语句的区别
1.一般情况下,他们两个是可以互相替换的
2.switch…case语句通常处理case为比较确定的值,而if…else…语句更加灵活,常用于大范围判断
3.switch语句进行条件判断后直接执行到程序的条件语句,效率更高。而if…else语句有几种条件,就得判断多少次
4.当分支比较少的时候,if…else语句的执行效率比switch语句高
5.当分支比较多的时候,switch语句的执行效率比较高,结构更清晰
循环语句
for循环
for(初始化变量;条件表达式;操作表达式){
? //循环体
}
初始化变量:就是var声明的一个普通变量,通常用于作为计数器使用
条件表达式:就是用来决定每一次循环是否继续执行,就是终止条件
操作表达式:是每次循环最后执行的代码,经常用于我们的计数器变量进行更新(递增或递减)
双重for循环
外层初始化循环执行一次,里面的循环执行全部
while循环
语法:
while(条件表达式){
? //循环体代码
}
执行思路:
1.先执行条件代码,如果结果为true,则执行循环代码。如果条件为false,则退出循环,执行后面代码
2.执行循环体代码
3.循环体代码执行完毕,程序会继续判断执行条件表达式,如条件仍true,则会继续执行循环体,知道循环条件为false时,整个循环过程才会结束。
do while循环
语法:
do{
? //循环体
}while(条件表达式)
执行思路:先执行一次,再判断条件
continue关键词
continue关键词用于立即跳出本次循环,继续下一次循环
break关键词
break关键词用于跳出整个循环(提前结束)
数组
数组的创建方式
利用new创建数组
格式:
var 数组名 = new Array();
var arr = new Array(); //创建一个新的空数组
利用数组字面量创建数组
格式:
var arr = [];
- 数组的字面量是用方括号[]
- 声明数组并赋值称为数组的初始化
- 这种字面量方式也是我们以后最多使用的方式
访问数组元素
格式:
console.log(数组名[索引号])
遍历数组
遍历:就是把数组中的每个元素从头到位的访问一次
数组新增元素
可以通过length长度以及索引号增加数组元素
通过修改length长度新增数组元素
格式:
arr.length = 4(你想要的长度);
引号增加数组元素
格式:
arr[4] = ‘你要添加的元素’;
函数
函数:函数就是封装了一段可以被重复调用执行的代码块
格式:
声明函数:
function 函数名(形参1,形参2…){
? //函数名
}
调用函数:
函数名(实参1,实参2…);
- 调用函数名千万别忘记加小括号
- 口诀:函数不调用,自己不执行
- 如果实参个数和形参一致,则正常输出结果
- 如果实参个数多余形参的个数,会取到形参个数
- 如果实参个数少于形参的个数,没有接受到值的形参结果是undefined
return
1.我们函数只是实现某种功能,最终结果需要返回给函数的调用者函数名()通过return实现
2.只要函数遇到return,就吧后面的结果返回给函数的调用者,函数名()= return后面的结果
3.return还有终止函数的作用,return之后不再执行代码
4.return只能返回一个值,如果有多个值,返回最后一个值,解决方法是使用数组
5.我们的函数值有return,则返回return后面的值。如果没有,则返回undefined
arguments的使用
当我们不确定有多少个传递的时候,可以用arguments来获取。在JavaScript中,arguments实际上它是当前函数的一个内置对象。所有函数都内置了一个arguments对象。arguments对象中存储了床传递的所有实参。
arguments展示形式是一个伪数组,因此可以进行遍历,伪数组具有以下特点:
- 具有length属性
- 按索引方式存储数据
- 不具有数组的push,pop等方法
作用域
通常来说,一段程序代码中所用到的名字并不总是有效和可用的,而限定这个名字的可用性代码范围就是这个名字的作用域。作用域的使用提高了程序逻辑的局部性,增强了程序的可靠性,减少了名字的冲突。分为全局作用域(函数内部没有声明直接赋值的变量也属于全局)和局部作用域(只在函数内部起作用)
全局变量和局部变量的区别:
- 全局变量在任何一个地方都可以使用,只有在浏览器关闭的时候才会被销毁,因此比较占内存
- 局部变量只在函数内部使用,当其所在代码块被执行的时候,会被初始化;当代码块运行结束后,就会被销毁,因此节省内存空间
作用域链
- 只要是代码,就至少有一个作用域
- 写在函数内部的局部作用域
- 如果函数中还有函数,那么在这个作用域中就又可以诞生一个作用域
- 根据在内部函数可以访问外部函数变量的这种机制,用链式查找决定哪些数据能被内部函数访问,就称作用域链
预解析
JavaScript代码是由浏览器中的JavaScript解析器来执行的。JavaScript解析器在运行JavaScript代码的时候分为两步:预解析和代码执行
1.预解析 js引擎会把js里面所有的var还有function提升到当前作用域的最前面
2.执行代码 按照代码书写的顺序从上到下执行
预解析分为变量预解析(变量提升)和函数预解析(函数提升)
1.变量提升:就是把所有的变量声明提升到当前的作用域最前面,不提升赋值操作
2.函数提升:就是把所有的函数声明提升到当前的作用域最前面,不调用函数
对象
什么是对象
在JavaScript中,对象是一组相关属性的方法的集合,所有事物都是对象,例如字符串,数值,数组,函数等。
对象是由属性和方法组成的
- 属性:事物的特征,在对象中属性来表示(常用名词)
- 方法:事物的行为,在对象中用方法来表示(常用动词)
创建对象
在JavaScript中,现阶段我们可以采用三种方式创建对象(object):
- 利用字面量创建对象
- 利用new object创建对象
- 利用构造函数创建对象
字面量创建对象
语法:
var obj = {属性名:值};
调用:obj.属性名 obj[‘属性名’]
1.里面的属性或方法我们采取键值对的形式
2.多个属性或者方法直接用逗号隔开
3.方法冒号后面跟的是一个匿名函数
4.调用对象的属性,我们采取对象.属性名
5.调用对象还有一种方法是 对象名[‘属性名’]
new Object创建对象
语法:
var obj = new Object();
obj.uname = ‘张三丰’;
obj.age = ‘128’;
1.这个是用等号赋值的方法添加对象的属性和方法
2.每个属性和方法之间用;结束
3.调用和上面的方法一致
构造函数创建对象
构造函数:是一种特殊的函数,主要用来初始化对象,即为对象成员赋初始值,它总与new运算符一起使用。我们可以把对象中一些公共的属性和方法抽取出来,然后封装到这个函数的里面
格式:
function 构造函数名称(uname,age,sex){
? this.name = uname;
? this.age = age;
? this.sex = sex;
}
var 变量 = new 构造函数名称 ();
1.构造函数名称首字母大写
2.构造函数不需要return就可以返回值
3.我们调用构造函数必须使用new
4.只要调用函数就创建了一个对象
5.属性方法前面必须加this
其中new的作用:
1.new在构造函数中创建了一个空的对象
2.this会指向new刚刚创建的空对象
3.执行构造函数的代码给new创建的空对象添加属性和代码
4.new最后放回对象
遍历对象
for (变量 in 对象){
}
内置对象
JavaScript中的对象分为三种:自定义对象,内置对象,浏览器对象
内置对象就是指js语言自带的一些对象,这些对象供开发者使用,并提供了一些常用或是最基本的必要功能(属性和方法)
JavaScript提供了多个内置对象:Math,Date,Array,string等
数组对象
检测是否为数组对象
1.arr instanceof Array
2.Array.isArray(arr)
添加和删除数组
方法名 | 说明 | 返回值 |
---|
push(参数1) | 末尾添加一个或多个元素 | 并返回新长度 | pop() | 删除数组最后一个元素,把数组长度减1无参数,修改原数组 | 返回它删除的元素的值 | unshift(参数1) | 向数组的开头添加一个或者多个元素 | 并返回新的长度 | shift() | 删除数组的第一个新元素,数组长度减1无参数,修改原数组 | 并返回第一个元素的值 |
数组排序
方法名 | 说明 | 是否修改原数组 |
---|
reverse() | 颠倒数组中元素的顺序,无参数 | 该方法会改变原来的数组,返回新数组 | sort() | 对数组的元素进行排序 | 该方法会改变原来的数组,返回新数组 |
数组索引办法
方法名 | 说明 | 返回值 |
---|
indexOf() | 数组中查找给定元素的第一个索引值 | 如果存在返回索引号,如果不存在,则返回-1 | lastIndexOf() | 在数组中的最后一个索引 | 如果存在返回索引号,如果不存在,则返回-1 |
数组转化为字符串
方法名 | 说明 | 返回值 |
---|
toString | 把数组转换成字符串,逗号分隔每一项 | 返回一个字符串 | join(‘分隔符‘) | 方法用于把数组中的所有元素转化为一个字符串 | 返回一个字符串 |
数组连接和多个删除
方法名 | 说明 | 返回值 |
---|
concat() | 连接两个或多个数组 不影响原数组 | 返回一个新数组 | slice() | 数组截取slice(begin,end) | 返回被截取项目的新数组 | splice() | 数组删除splice(第几个开始,要删除几个) | 返回被删除项目的新数组,注意,这个会影响原数组 |
slice()和splice()目的基本相同,建议了解splice
字符串对象
基本包装类型:就是把简单数据类型包装成了复杂数据类型,让简单的数据类型有了属性和方法
字符串不可变性:字符串里面的值不可变,虽然看上出内容变了,但其实地址变了,内存中新开辟了一个内存空间。
根据字符返回位置
字符串所有的方法都不会改变字符串本身(字符串是不可变的),操作完成会返回一个新的字符串
方法名 | 说明 |
---|
indexOf(‘要查找的字符’,开始的位置) | 返回指定内容的原字符串中的位置,如果找不到就返回-1,开始的位置是index索引号 | lastIndexOf() | 从后往前找,只找第一个匹配的 |
格式:
字符串变量.indexOf(‘变量中的字’,[从第几个开始])
根据位置返回字符串
方法名 | 说明 | 使用 |
---|
charAt(index) | 返回指定位置的字符(index字符串的索引号) | str.charAt(0) | charCodeAt(index) | 获取指定位置处字符的ASCII码(index索引号) | str.charCodeAt(0) | str[index] | 获取指定位置处字符 | HTML,IE8-支持和charAt等效 |
字符串操作方法
方法名 | 说明 |
---|
concat(str1,str2,str3) | concat()方法用于连接两个或多个字符,拼接字符串,等效于+,+更常用 | substr(start,length) | 从star位置开始(索引号),length取的个数,重点 | slice(star,end) | 从star位置开始,截取到end位置,end取不到(他们两个都是索引号) | substring(star,end) | 从start位置开始,截取到end ,end取不到 基本和slice相同,但是不接受负值 |
简单数据类型与复杂数据类型
简单类型又被叫做基本数据类型或者值类型,复杂类型又叫做引用类型
- 值类型:简单数据类型/基本数据类型,在储存变量中储存的是值本身,因此叫做值类型:string,number,boolean,undefined,null
- 简单数据类型是存放在栈里面,里面直接开辟一个空间存放的是值
- 引用类型:复杂数据类型,在存储时变量中存储的仅仅是地址(引用),因此叫做引用数据类型,通过new关键字创建的对象(系统对象,自定义对象),如Object,Array,Date等
- 复杂数据类型首先在栈里面存放地址,十六进制表示,然后在这个地址指向堆里面的数据
堆和栈
堆栈空间分配区别:
1.栈(系统操作):由操作系统自动分配释放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈;简单数据类型存放在栈里面
2.堆(操作系统):存储复杂数据类型(对象),一般由程序员分配释放,若程序员不释放,由垃圾回收机制回收。复杂数据类型存放在堆里面
简单数据类型传参
函数的形参也可以看做是一个变量,当我们把一个值类型变量作为参数传给函数的形参时,其实就是把变量在栈看见里的值复制给了一份给形参,那么在方法内部对形参做任何修改,都不会影响到外部变量
复杂数据类型传参
函数的形参也可以看做是一个变量,当我们把一个引用类型变量作为参数传给函数的形参时,其实就是把变量在栈里保存的堆地址复制给了一份给形参,形参和实参其实保存的是同一个地址,所以操作的是同一个对象
DOM
DOM树
- 文档:一个页面就是一个文档,DOM中使用document表示
- 元素:页面中的所有标签都是元素,DOM中使用element表示
- 节点:网页中所有的内容都是节点(标签,属性,文本,注释等),DOM中使用node表示
获取元素
1.根据ID获取
语法:
var element = document.getElementById(id);
参数id是大小敏感的字符串
2.根据标签名获取
语法:
var element = document.getElementsByTagName(‘标签名’);
父元素必须是单个对象(必须指明是哪一个元素对象),获取的时候不包括父元素自己
返回的是获取过来元素的对象集合,以伪数组的形式存储的
注意:
- 因为得到的是一个对象的集合,所以我们想要操作里面的元素就需要遍历
- 得到元素对象是动态的
- 如果里面只有一个标签,返回的还是伪数组的形式
- 如果里面没有这个标签,返回的是一个空的伪数组
3.通过html5新增方法获取
语法:
1.document.getElementsByClassName(‘类名’);
2.document.querySelector(‘选择器’);返回指定选择器的第一个元素对象
3.document.querySelectorAll(‘选择器’);根据指定选择器返回
4.获取body和html元素
获取body:
document.body;
获取html
document.documentElement;
事件基础
JavaScript使我们有能力创建动态页面,而事件是可以被JavaScript侦测到的行为。触发响应的一种机制
事件由三部分组成:事件源,事件类型,事件处理程序
事件源是事件被触发的对象
事件类型 如何触发 什么事件 比如鼠标点击(onclick),鼠标经过,还是键盘按下
事件处理程序是通过一个函数赋值的方式完成
执行事件的步骤
1.获取事件源
2.注册事件(绑定事件)
3.添加事件处理程序(采取函数赋值形式)
鼠标事件 | 触发条件 |
---|
onclick | 鼠标点击左键触发 | onmouseover | 鼠标经过触发 | onmouseout | 鼠标离开触发 | onfocus | 获得鼠标焦点触发 | onblur | 失去鼠标焦点触发 | onmousemove | 鼠标移动触发 | onmouseup | 鼠标弹起触发 | onmousedown | 鼠标按下触发 |
操作属性
JavaScript的DOM操作可以改变网页内容,结构和样式,我们可以利用DOM操作元素来改变元素里面的内容,属性等。注意以下都是属性
改变元素的内容
语法:
1.element.innerText
从起始位置到终止位置的内容,但它去除html标签,同时空格和换行也会去掉,不识别html标签
2.element.innerHTML
起始位置到终止位置的全部内容,包括html标签,同时保留空格和换行,识别html标签
表单元素的属性操作
type、value、checked、selected、disabled
样式属性操作
1.element.style 行内样式操作
2.element.className 类名样式操作
注意:
1.JavaScript里面的样式采用驼峰命名法,比如fontSize,backgroundColor
2.JavaScript修改style样式操作,产生的是行内样式,css权重比较高
3.如果样式修改比较多,可以采用操作者类名样式更改元素样式
4.class因为是个保留字,一次使用className来操作元素类名属性
5.className会直接元素的类名,会覆盖原先的类名
自定义属性操作
获取属性值
格式:
1.element.属性;
2.element.getAttribute(‘属性’);
区别:
- element.属性; 获取的是内置属性值(元素本身自带的属性)
- element.getAttribute(‘属性’); 主要获得自定义的属性(标准)
设置属性值
- element.属性 = ‘值’; 设置内置属性值
- element.setAttribute(‘属性’,‘值’);
区别:
- element.属性 = ‘值’; 设置内置属性值
- element.setAttribute (‘属性’,‘值’); 主要设置自定义属性(标准)
移除属性值
element.removeAttribute (‘属性’);
H5自定义属性
自定义属性的目的:是为了保存并且使用数据。有些数据可以保存到页面中而不用保存到数据库中
H5规定自定义属性统一data-开头作为属性名并赋值
例如:<div data-index=‘1’></div>
H5新增了获取自定义属性的办法,element.dateset.index
dateset是date的集合,里面包含了所有date开头的属性
节点操作
节点概述
一般地,节点至少有node.Type(节点类型),nodeName(节点名称),和nodeValue(节点值)这三个基本属性
- 元素节点 nodeType为1
- 属性节点 nodeType为2
- 文本节点nodeType为3(文本节点包括文字,空格和换行等)
节点操作主要操作元素节点
节点层级
利用DOM树可以把节点划分为不同的层级关系,常见的是父子兄层级关系
1.父级节点
语法:
node.parentNode
2.子节点
语法:
1.parentNode.childNodes(标准)
nodeparent.childNodes返回包括指定节点的子节点的集合,该集合及时更新的集合(包含元素节点和文本节点)
如果想要获得里面的元素节点,则需要专门处理,所以一般不提倡用childNodes
2.parentNode.children(非标准)
parentNode.children是一个只读属性,返回所有的子元素节点。它只返回子元素节点,其余节点不返回
虽然children是一个非标准,但是得到了各个浏览器支持
获取第一个子节点和最后一个
语法:
1.parentNode.firstChild(第一个子节点,不管是文本节点还是元素节点)
2.parentNode.lastChild(最后一个子节点,不管是文本节点还是元素节点)
3.parentNode.firstElementChild(第一个子元素节点)
4.parentNode.lastElementChild(最后一个子元素节点)
5.parentNode.children[0];(一样可以取到第一个子元素节点)
6.parentNode.children[parentNode.Children.length - 1];
3.兄弟节点
语法:
1.node.nextSibling
nextsibling返回当前元素的下一个兄弟节点,找不到则返回null,同样,也是包含所有节点
2.node.previousSibling
previoussibling返回当前元素的上一个兄弟节点,找不到则返回null。同样,也是包含所有的节点
3.node.nextElementSibling
nextElementSibling返回当前元素的下一个兄弟元素节点,找不到则返回null
4.node.previousElementSibling
previousElementSibling返回当前元素的上一个兄弟元素节点,找不到则返回null
创建节点
语法:
document.createElement(‘tagName’);
document.createElement(‘tagName’);创建由tagName指定的HTML元素,因为这些元素原先不存在,是根据我们的需求动态生成的,所以我们也称为动态创建元素节点
添加节点
语法:
1.node.appendChild(child);
node.appendChild()方法将一个节点添加到指定父节点的子节点列表末尾。类似于css里面的after伪元素
2.node.insertBefore(child,指定元素)
node.insertBefore()方法将一个节点添加到指定父节点的子节点列表前面。类似于css里面的before伪元素
删除节点
node.removeChild(child);
node.removeChild()方法从DOM中删除一个子节点,返回删除的节点
复制节点(克隆)
语法:
node.cloneNode()
node.cloneNode()方法返回调用该方法的节点的一个副本,也称为克隆节点
注意:如果括号参数为空或者为false,则是浅拷贝,即只克隆复制节点本身,不克隆里面的子节点,如果括号里为ture为深拷贝
三种动态创建元素区别
- document.write()
- element.innerHTML
- document.createElement()
区别:
1.document.write()是直接将内容写入页面内容流,但是文档流执行完毕,则它会导致页面全部重绘
2.innerHTML 是将内容某个DOM节点,不会导致页面全部重绘
3.innnerHTML创建多个元素效率更高(不拼接字符,采取数组形式拼接),结构稍微复杂
4.createElement()创建多个元素的效率稍微低一点点,但是结构更清晰
DOM重点核心
文档对象模型,是w3c组织推荐的处理可扩展标记语言(HTML或者XML)的标准编程接口
w3c已经定义了一系列的DOM接口,通过DOM接口可以改变网页内容,结构和样式
对于JavaScript,为了能够使JavaScript操作HTML,JavaScript就有了自己的一套自己的dom编程接口
对于HTML,dom使得html形成一颗dom树,包含:文档,元素,节点
DOM高级事件
注册事件
给元素添加事件,称为注册事件或者绑定事件
分为:传统方式和方法监听注册方式
传统方式
- 利用on开头的事件onclick
- <btton onclick = 'alert(‘hi)’></button>
- btn.onclick = function(){}
- 特点:注册事件的唯一性
- 同一个元素同一个事件只能设置一个处理函数,最后注册的处理函数将会覆盖前面注册的处理函数
方法监听注册方式
- w3c标准推荐方式
- addEventListener()它是一个方法
- IE9以前是IE不支持这个方法,可使用attachEvent代替
- 特点:同一个元素同一个事件可以注册多个监听器
- 按注册顺序依次执行
事件监听方式
eventTarget.addEventListener(type,listener[,useCapture])
eventTarget.addEventListener()方法将指定的监听器注册到eventTarget(目标对象)上,当该对象触发指定事件的时候,就会执行事件处理函数
该方法接收三个参数:
-
type:事件类型字符串,例如click,mouseover,注意这些不带on -
listener:事件处理函数,事件发生时,会调用该监听函数 -
useCapture:可选参数,是一个布尔值,默认是false
attachEcent事件监听方式(支持IE9以前)
语法:
eventTarget.attachEvent(eventNameWithOn,callback)
eventTarget.attachEvent()方法将指定的监听器注册到eventTarget(目标对象上),当该对象触发指定的事件时,指定回溯函数就会被执行
该方法接收两个参数:
- eventNameWithOn:事件类型字符串,比如onclick,onmouseover,这里要带on
- callback:事件处理函数,当目标触发事件时回溯函数被使用
删除事件(解绑事件)
传统事件方式
eventTarget.onclick = null;
方法监听注册方式
1.eventTarget.removeEventListener(type,listener[,userCapture]);
2.eventTarget.detachEvent(eventNameWithOn,callback);(ie9以下)
DOM事件流
事件流描述是从页面中接收事件的顺序
事件发生会在元素节点之间按照特定的顺序传播,这个传播过程即DOM事件流
DOM事件流分为3个阶段:
1.捕获阶段
2.当前目标阶段
3.冒泡阶段
- 事件冒泡:IE最早提出,事件开始时由最具体的元素接收,然后逐级向上传播到DOM最顶层节点的过程
- 事件捕获:网景最早提出,由DOM最顶层节点开始,然后逐层向下传播到最具体的元素接收的过程
有些事件是没有冒泡的,比如onblur,onfocus,onmouseenter,onmouseleave
事件对象
div.onclick = function(event){}; 这event就是事件对象
-
事件对象只有有了事件才会存在,他是系统给我们自动创建的,不需要我们传递参数 -
事件对象是我们事件一系列相关数据的集合,跟事件相关的。比如鼠标点击里面就包含了鼠标的相关信息,鼠标坐标,如果是键盘事件里面就包含的键盘事件的信息。比如用户按下了哪个键 -
这个事件对象我们自己命名,比如event,evt,e -
事件对象也有兼容性问题,ie678通过window.event兼容
事件对象的常见属性和方法
事件对象属性方法 | 说明 |
---|
e.target | 返回触发事件的对象 标准 | e.srcElement | 返回触发事件的对象 非标准 | e.type | 返回事件的类型 比如click,mouseover 不带on | e.cancelBubble | 该值阻止冒泡, 非标准 ie6-8使用 | e.returnValue | 该属性阻止默认事件(默认行为) 非标准 ie6-8使用 比如不让链接跳转 | e.preventDefault() | 该方法阻止默认事件(默认行为) 标准 比如不让链接跳转 | e.stopPropagation | 阻止冒泡 标准 |
e.target和is的区别
e.target返回的是触发事件的对象(元素)
this返回的是绑定事件的对象(元素)
阻止冒泡的两种方式
事件冒泡:开始时由最具体的元素接收,然后逐级向上传播DOM最顶层节点。
- 标准写法:利用事件对象里面的stopPropagation()方法
- 不标准写法:e.cancelBubble
事件委托
事件委托也称为事件代理,在jQuery里面称为事件委派
事件委托的原理
不是每个子节点单独设置监听器,而是事件监听器设置在其父节点上,然后利用冒泡原理影响设置每个子节点
事件委托作用
我们只操作了一次DOM,提高了程序性能
另外一些常用的鼠标事件
1.禁止鼠标右击菜单
contextmenu主要控制该何时显示上下文菜单,主要用于程序员取消默认的上下文菜单
语法:
document.addEventListener(‘contextmenu’, function (e) {
? e.preventDefault()
? })
2.禁止鼠标选中(selectstart 开始选中)
语法:
document.addEventListener(‘selectstart’, function (e) {
? e.preventDefault()
? })
鼠标事件对象
event对象表示事件的状态,跟事件相关的一系列信息的集合。我们主要是用鼠标事件的对象MouseEvent和键盘事件对象KeyboardEvent
鼠标事件对象 | 说明 |
---|
e.clientX | 返回鼠标相对于浏览器窗口可视区的X坐标 | e.clientY | 返回鼠标相对于浏览器窗口可视区的Y坐标 | e.pageX | 返回鼠标相对于文档页面的X坐标 | e.pageY | 返回鼠标相对于文档页面的Y坐标 | e.screenX | 返回鼠标相对于电脑屏幕的X坐标 | e.screenY | 返回鼠标相对于电脑屏幕的Y坐标 |
常用的键盘事件
键盘事件 | 触发条件 |
---|
onkeyup | 某个键盘按键被松开时触发 | onkeydown | 某个键盘按键被按下时触发 | onkeypress | 某个键盘按键被按下时 触发 但是它不识别功能键 比如ctrl shift 箭头等 |
三个事件的执行顺序先keydown后keypress最后keyup
判断用户按下哪个键keyCode
语法:
document.addEventListener(‘keyup’, function (e) {
? console.log(e.keyCode);
? })
注意:
我们的keyup和keydown不区分字母大小写,带小写字母a/A都得到65,press区分大小写,A为65,a为97
DOM和BOM的区别
DOM
- 文档对象模型
- DOM就是把文档当做一个对象来看待
- DOM的顶级对象是document
- DOM是w3c标准规范
BOM
- 浏览器对象模型
- 把浏览器看做一个对象看待
- BOM顶级对象是window
- BOM是浏览器厂商在各自浏览器上定义的,兼容性比较差
BOM
BOM即浏览器对象模型,它提供了独立于内容而与浏览器窗口进行交互的对象,其核心对象是window
window对象是浏览器的顶级对象,它具有双重角色。
1.它是JS访问浏览器窗口的一个接口
2.它是一个全局对象,定义在全局作用域中的变量,函数都会变成window对象的属性和方法
窗口加载事件
语法:
window.onload = function(){}
或者
window.addEventListener(‘load’,function(){})
window,onload是窗口(页面)加载事件,当文档内容完全加载完成会触发该事件(包括图像,脚本文件,CSS文件等)就调用的数据函数
注意:
1.有了window.onload就可以把JS代码写到网页元素的上方,因为onload是等页面内容全部加载完毕,再去执行处理函数
2.window.onload传统注册事件方式只能写一次,如果有多个,会以最后一个window.onload为准
3.如果使用addEventListener则没有限制
语法:
document.addEventListener(‘DOMContentLoaded’,function(){})
DOMcontentLoaded事件触发时,仅当DOM加载完成时,不包括样式表,图片,flash等等
如果页面的图片很多的话,从用户访问到onload触发可能需要很久时间,交互效果就不能实现,必然影响用户的体验,此时用DOMContentLoaded事件比较合适
调整窗口大小事件
语法:
1.window.onresize = function(){};
2.window.addEventListener(‘resize’,function(){});
window.onresize是调整窗口大小加载事件,当触发时就调整的处理函数
注意:
1.只要窗口大小发生变化,就会触发这个事件
2.我们经常用这个事件完成响应式布局,window.innerWidh当前屏幕的宽度
定时器
window对象给我们提供了两个非常好用的方法 定时器
- setTimeout()
- setInterval()
setTimeout()定时器
语法:
window.setTimeout(调用函数,[延迟的毫秒数]);
setTimeoout()方法用于设置一个定时器,该定时器在定时器到期后执行调用函数。
注意:
1.这个window在调用的时候可以省略
2.这个延迟时间单位是毫秒,但是可以忽略,如果忽略默认值是0
3.这个调用函数可以直接写函数,还可以写函数名,还有一个写法 ‘函数名() ’
4.页面中可能会有很多定时器,经常给定时器加标识符
5.setTimeoout这个调用的函数也称为回调函数callback
普通函数是按代码顺序直接调用,而这个函数,需要等待时间,时间到了采取调用这个函数,因此称为回调函数。
onclick也是回调函数
停止setTimeout()定时器
语法:
window.clearTimeout(timeoutID)
注意:
1.window可以省略
setInterval()定时器
window.setInterval(回调函数,{间隔的毫秒数});
setInterval()方法重复调用一个函数,每个这个时间,就去调用一次回调函数
注意:
1.window可以省略
2.这个函数可以直接写函数,或者写函数名或者采取字符串‘函数名()’三种形式
3.间隔毫秒是可以省略的,默认是0,必须是毫秒,表示每隔多少毫秒自动启动这个函数
停止setInterval()定时器
window.clearInterval(interval ID);
clearInterval()方法取消了先前通过调用setInterval()建立的定时器
注意:
1.window可以省略
2.里面的参数就是定时器标识符
this指向问题
1.在全局作用域或者普通函数中this指向全局对象window(注意定时器里面的this指向window)
2.方法调用中谁调用this指向谁
3.构造函数中this指向构造函数的实例
JS执行机制
JS语言的一大特点就是单线程,也就是说,同一时间只能做一件事
同步和异步
为了解决单线程利用效率低问题,利用多核CPU的计算能力,HTML5提出WEB Worker标准,允许JavaScrip脚本创建多个线程。于是,JS中出现了同步和异步
同步
前一个任务结束后执行后一个任务,程序的执行与任务排列顺序一致的,同步的,比如做饭的同步做法:我们要烧水煮饭,等水开了,再去切菜,炒菜
异步
你在做一件事,因为这件事情会花费很长时间,在做这件事的同时,你还可以去处理其他事情,不如做法的异步做法,我们在烧水的同时,利用这烧水的时间,去切菜,炒菜。
同步任务
同步任务都在主线程上进行,形成一个执行栈。
异步任务
JS的异步是通过回调函数实现的
一般而言,异步任务有以下三种类型:
1.普通事件,如同click,resize等
2.资源加载,如load,error等
3.定时器,包括setInterval,setTimeout等
异步任务相关的回调函数添加到任务队列中(任务队列也称为消息队列)
JS执行机制
1.先执行执行栈的同步任务
2.异步任务(回调函数)放入任务队列中
3.一旦执行栈中的所有同步任务执行完毕,系统就会按次序读取任务队列中的异步任务,对于被读取的异步任务结束等待状态,进入执行栈,开始执行
由于主线程不断重复获得任务,执行任务,再获取任务,再执行,所以这种机制被称之为事件循环(event loop)
location对象
window对象给我们提供了一个location属性用于获取或设置窗体的URL,并且可以用于解析URL。因为这个属性返回的是一个对象,所以我们将这个属性也称为location对象
URL是什么
URL是统一资源定位符,是互联网上标准资源的地址。互联网的每个文件都有一个唯一的URL,它包含的信息指出文件的位置以及浏览器应该怎么处理它。
URL一般语法:
protocol://host[:port]/path/[?query]#fragment
http://www.itcast.cn/index.html?name=andy&age=18#link
组成 | 说明 |
---|
protocol | 通信协议 常用的http,ftp,maito等 | host | 主机(域名) www.itheima.com | port | 端口号 可选 省略时使用方案的默认端口 如http的默认端口为80 | path | 路径 零或多个‘/’符号隔开的字符串,一般用来表示主机上的目录或文件地址 | query | 参数 以键值对的形式,通过&符号隔开 | fragment | 片段 #后面内容 常用于链接 锚点 |
location对象的属性
location对象属性 | 返回值 |
---|
location.href | 获取或设置 整个URL | location.host | 返回主机(域名) www.itheima.com | location.port | 返回端口号 如果没写返回空字符串 | location.pathname | 返回路径 | location.search | 返回参数 | location.hash | 返回片段 #后面内容 常见于链接 锚点 |
location对象方法
location对象方法 | 返回值 |
---|
location.assign() | 跟href一样,可以跳转页面(也称为重定向页面) | location.replace() | 替换当前页面,因为不记录历史,所以不能后退页面 | location.reload | 重新加载页面,相对于刷新或者f5 如果参数为true强制刷新ctlr + f5,f |
navigator对象
navigator对象包含浏览器的信息,他有很多属性,我们最常用的是userAgent,该属性可以返回由客户机发送服务器的user-agent头部的值
history对象
window对象给我们提供了一个history对象,与浏览器历史记录进行交互,该对象包括用户(在浏览器窗口中)访问过的URL
history对象方法 | 作用 |
---|
back() | 可以退后功能 | forward() | 前进功能 | go(参数) | 前进后退功能 参数如果是1 前进一个页面 如果是-1 退后一个页面 |
网页特效
元素偏移量 offset系列
offset属性可以动态的得到该元素的位置(偏移),大小等。
- 获得元素距离带有定位父元素的位置
- 获取元素自身的大小(宽度高度)
- 注意:返回的数值不带单位
offse系列常用的属性:
offset系列属性 | 作用 |
---|
element.offsetParent | 返回作为该元素带有定位的父元素,如果父元素没有定位则返回body | element.offsetTop | 返回元素相对带有定位父元素上方偏移 | element.offsetLeft | 返回元素相对带有定位父元素左边框的偏移 | element.offsetWidth | 返回自身包括paddding,边框,内容区的宽度,返回值不带单位 | element.offsetHeight | 返回自身包括paddding,边框,内容区的高度,返回值不带单位 |
offset和style区别
offset
- offset可以得到任意样式表中的样式值
- offset系列获得的数值没有单位
- offsetWidth包括padding+border+width
- offsetWidth等属性是只读属性,只能获取不能赋值
- 所以我们想要获取元素大小位置,用offset更合适
style
- style只能得到行内样式表中的样式值
- style.width获得的是带有单位的字符串
- style.width获得不包括padding和border的值
- style.width是可读写属性,可以获取也可以赋值
- 所以,,我们想给元素更改值,则需要用style
元素可视区client系列
client翻译过来就是客户端,我们使用client系列的相关属性来获取元素可视区的相关信息。通过client系列的相关属性可以动态得到该元素的边框大小,元素大小等
client系列属性 | 作用 |
---|
element.clientTop | 返回元素上边框大小 | element.clientLeft | 返回元素左边框大小 | element.clientWidth | 返回自身包括padding,内容区的宽度,不含边框,返回值不带单位 | element.clientHeight | 返回自身包括padding,内容区的高度,不含边框,返回值不带单位 |
立即执行函数
不需要调用,立马能够自己执行的函数
语法:
1.(function(){})();
2.(function(){}());
元素滚动scroll系列
scroll翻译过来就是滚动。我们使用scroll系列的属性可以动态的得到该元素的大小,滚动距离等。
scroll系列属性 | 作用 |
---|
element.scrollTop | 返回被卷去的上侧距离,返回数值不带单位 | element.scrollLeft | 返回被卷去的左侧距离,返回数值不带单位 | element.scrollWidth | 返回自身实际的宽度,不含边框,返回数值不带单位 | element.scrollHeight | 返回自身实际的高度,不含边框,返回数值不带单位 |
页面被卷去头部是window.pageYOffset,左侧是window.pageXOffset
mouseenter和mouseover的区别
- 当鼠标移动到元素上时就会触发mouseenter事件
- 类似mouseover,他们两个之间的差别是
- mouseover鼠标经过自身盒子会触发,经过子盒子还会触发一次,mouseenter只有经过自身盒子会触发
- 之所以这样,就因为mouseenter不会冒泡
动画函数封装
动画实现的原理
核心原理:通过定时器setInterval不断移动盒子位置
实现步骤:
1.获得盒子当前位置
2.让盒子在当前位置加上1个移动距离
3.利用定时器不断重复这个操作
4.加一个结束定时器的条件
5.注意此元素需要添加定位,才能使用element.style,left
动画函数简单封装
注意函数需要传递2个参数,动画对象和移动到的距离
缓动动画原理
缓动动画就是让元素运动速度有所变化,最常见的是让速度慢慢停下来
思路:
1.让盒子每次运动的距离慢慢减小,速度就会慢下来
2.核心算法:(目标值-现在的位置)/10 作为每次移动的距离步长
3.停止条件是:让当前盒子位置等于目标位置就停止定时器
动画函数添加回调函数
回调函数:函数可以作为一个参数,将这个函数作为参数传到另外一个函数里面,当那个函数执行完之后,再执行进去的这个函数,这个过程叫做回调。
回调函数写的位置,定时器结束的位置
节流阀
防止轮播图按钮连续点击造成播放过快
节流阀目的:当上一个函数动画内容执行完毕,再去执行下一个函数动画,让时间无法连续触发
核心实现思路:利用了回调函数,添加一个变量来控制,锁住函数和解锁函数
开始设置一个变量var flag = true
if(flag)(flag = false;do something)
利用回调函数 动画执行完毕,flag=true 打开
移动端网页特效
移动端触屏事件
触屏touch事件 | 说明 |
---|
touchstart | 手指触摸到一个DOM元素时触发 | touchmove | 手指在一个DOM元素上滑动时触发 | touchend | 手指从一个DOM元素上移开时触发 |
触摸事件对象(touchEvent)
TouchEvent是一类描述手指在触摸平面(触摸屏,触摸板等)的状态变化的事件。这类事件用于描述一个或多个触点,使开发者可以检查触点的移动,触点的增加或减少,等等
touchstart,touchmove,touchend三个事件都会有各自的事件对象
触摸事件对象常见对象列表
触摸列表 | 说明 |
---|
touches | 正在触摸屏幕的所有手指的一个列表 | targetTouches | 正在触摸当前DOM元素上的手指的一个列表 | changedTouches | 手指状态发生了改变的列表,从无到有,从有到无变化 |
移动端拖动元素
1.youchstart,touchmove,touchchanged可以实现拖动元素
2.但是拖动元素需要当前手指的坐标值,我们可以使用targetTouches[0]里面的pageX和pageY
3.移动端拖动原理:手指移动中,计算出手指的距离,然后用盒子原来的位置+手指移动的距离
4.手指移动的距离:手指滑动的位置减去手指刚开始触摸的位置
拖动元素三部曲
(1)触摸元素touchstart:获取手指初始坐标,同时获得盒子原来的位置
(2)移动手指touchmove:计算手指滑动的距离,并且移动盒子
(3)离开手指touchend
注意:手指移动也会触发滚动屏幕所以这里要阻止默认的屏幕滚动e.preventDefault();
classList属性
classList属性HTML5新增的一个属性,返回元素类名
添加类:element.classList.add(‘类名’);
移除类:element.classList.remove(‘类名’);
切换类:element.classList.toggle(‘类名’);
click延迟解决方案
移动端click事件会有300ms的延迟,原因是移动端屏幕双击会缩放(double tap to zoom)页面
解决方案:
1.禁用缩放,浏览器禁用默认的双击缩放行为并且去掉300ms点击延迟
2.利用touch事件对自己封装这个事件解决300ms延迟
原理:
3.使用插件fastclick来解决
本地存储
本地存储特性
1.数据存储在用户浏览器中
2.设置,读取方便,设置页面刷新不丢失数据
3.容量较大,sessionStorage约5m,localStorage约20m
4.只能存储字符串,可以将对象JSON.stringify()编码后存储
window.sessionStorage
1.生命周期为关闭浏览器窗口
2.在同一个窗口(页面)下数据可以共享
3.以键值对的形式存储使用
数据存储:
sessionStorage.setItem(key,value)
获取数据:
sessionStorage.getItem(key)
删除数据:
sessionStorage.removeltem(key)
删除所有数据:
sessionStorage.clear()
window.localStorage
1.生命周期永久生效,除非手动删除,否则关闭页面也会存在
2.可以多窗口(页面)共享(同一浏览器可以共享)
3.以键值对的形式储存使用
存储数据:
localStorage.setItem(key,value)
获取数据:
localStorage.getItem(key)
删除数据:
localStorage.removeItem(key)
删除所有数据:
localStorage.clear()
|