前端的修行之路-javaScript

前端的修行之路-javaScript

javaScript

输入输出语句

  • alert(msg):浏览器弹出警示框。

  • console.log(msg):浏览器控制台打印输出信息。

  • prompt(info):浏览器弹出输入框,用户可以输入。

变量

变量是内存里的一块空间,用来存储数据。

注意事项

  • 通常用var关键词来声明变量。
  • 一个变量被重新赋值后,它原有的值就会被覆盖,变量值将以最后一次赋的值为准。
  • 同时声明多个变量时,只需要写一个var,多个变量名之间使用英文逗号隔开。

命名规范

  • 由字母(A-Za-z)、数字(0-9)、下划线(_)、美元符号($)组成。
  • 严格区分大小写。
  • 不能以数字开头。
  • 不能是关键字、保留字。
  • 变量名必须有意义。
  • 遵守驼峰命名法。首字母小写,后面单词的首字母需要大写。

数据类型

简单数据类型

  • 简单类型又叫做基本数据类型或者值类型。
  • 值类型:简单数据类型/基本数据类型,在存储时变量中存储的是值本身,因此叫做值类型。
  • (操作系统):由操作系统自动分配释放存放函数的参数值、局部变量的值等。简单数据类型存放到栈里面。
  • 简单类型传参:函数的形参也是看做是一个变量,当把一个值类型变量作为参数传给函数的形参时,其实是把变量在栈空间里的值复制了一份给形参,那么在方法内部对形参做任何修改,都不会影响到的外部变量。

Number

Number:数字型,包含整型值和浮点型值。默认值为0。

  • 八进制:数字前加0,范围为0~7。
  • 十六进制:数字前加0x,范围为09和af。
  • Number.MAX_VALUE:数值的最大值(1.7976931348623157e+308)。
  • Number.MIN_VALUE:数值的最大值(5e-324)。
  • Infinity:代表无穷大,大于任何数值。
  • -Infinity:代表无穷小,小于任何数值。
  • NaN:Not a number,代表一个非数值。
  • isNaN:判断非数字。如果是数字为false,否则为true。

String

String:字符串类型,字符串都带引号。默认值为""。

  • 字符串嵌套:可以用单引号嵌套双引号,或者用双引号嵌套单引号(外双内单,外单内双)。
  • 字符串转义符:都是\开头的。
  • 字符串拼接:可以使用+进行拼接,其拼接方式为字符串+任何类型=拼接之后的新字符串
转义符 解释说明
\n 换行符
\ 斜杠
单引号
" 双引号
\t tab缩进
\b 空格
  • str.length:获取整个字符串的长度。

Boolean

Boolean:布尔值类型,如true、false,等价于1和0。默认值为false。

Undefined

undefined:没有赋值。默认值为undefined。

  • undefined和数字相加,结果是NaN。

Null

null:空值。默认值为null。

扫描二维码关注公众号,回复: 11056935 查看本文章
  • null和数字相加,结果是数字。

获取变量数据类型

  • typeof:可用来获取检测变量的数据类型。

数据类型的转换

字符串的转换

  • 使用num.toString()转成字符串。
  • 使用String()强制转换成字符串。
  • 和字符串拼接转换成字符串。

数字型的转换

  • 使用parseInt(String)将string类型转成整数数值型。
  • 使用parseFloat(string)将string类型转成浮点数数值型。
  • 使用Number()强制将string类型转成数值型。
  • 利用算术运算隐式转换为数值型。
  • 如果前面为数字,后面是非数字,转换时,只保留数字。
  • 如果前面为非数字,后面为数字,转换的结果是NaN。

布尔型的转换

  • 使用Boolean()强制将其他类型转成布尔值

  • 代表空、否定的值会被转换为false,如’’、0、NaN、null、undefined。

  • 其余值都会被转换为true。

复杂数据类型

  • 复杂类型又叫做引用类型。
  • 引用类型:复杂数据类型,在存储时变量中存储的仅仅是地址(引用),因此叫做引用数据类型。
  • (操作系统):存储复杂类型(对象),一般由程序员分配释放,若程序员不释放,由垃圾回收机制回收。复杂类型存放到堆里面。
  • 复杂类型传参:函数的形参也是看做是一个变量,当把一个值类型变量作为参数传给函数的形参时,其实是把变量在栈空间里保存的堆地址复制给了形参,形参和实参其实保存的是同一个堆地址,所以操作的是同一个对象。

运算符

运算符也被称为操作符,是用于实现复制比较执行算数运算等功能的符号。

常用的运算符有:算数运算符递增和递减运算符比较运算符逻辑运算符赋值运算符

算数运算符

运算符 描述
+
-
*
/
% 取余数(取模)
  • 进行算术计算时,浮点数精确度远远不如整数。
  • 不要直接判断两个浮点数是否相等。

递增和递减运算符

递增(++)和递减(–)既可以放在变量前面,也可以放在变量后面。放在变量前面时,称为前置递增(递减)运算符,放在变量后面时,称为后置递增(递减)运算符

  • 递增和递减运算符必须和变量配合使用。
  • 前置递增(递减),先自加(自减),后返回值。
  • 后置递增(递减),先返回值),后自加(自减)。

比较运算符

比较运算符是两个数据进行比较时所使用的运算符,比较运算后,会返回一个布尔值作为比较运算的结果。

运算符名称 说明
< 小于号
> 大于号
>= 大于等于号
<= 小于等于号
== 判等号(会转型)
!= 不等号
=== !== 全等 要求值和数据类型都一致

逻辑运算符

逻辑运算符是用来进行布尔值运算的运算符,其返回值也是布尔值。

逻辑运算符 说明
&& 逻辑与,简称与(and),两边都是true才为true
|| 逻辑或,简称或(or),两边都是false才为false
! 逻辑非,简称非(not),取反
  • 短路运算的原理:当有多个表达式(值)时,左边的表达式值可以确定结果时,就不再继续运算右边的表达式值。
  • 逻辑与的短路运算:如果第一个表达式的值为真,则返回表达式2;如果第一个表达式的值为假,则返回表达式1。
  • 逻辑或的短路运算:如果第一个表达式的值为真,则返回表达式1;如果第一个表达式的值为假,则返回表达式2。
  • 除了0’’nullundefined的为假,其余都是真的。

赋值运算符

赋值运算符是用来把数据赋值给变量的运算符。

赋值运算符 说明
= 直接赋值
+=、-= 加、减一个数后在赋值
*=、/=、%= 乘、除、取模后在赋值

运算符优先级

运算符 顺序
小括号 ()
一元运算符 ++ – !
算数运算符 先* / %后+ -
关系运算符 > >= < <=
相等运算符 == != === !==
逻辑运算符 先&&后||
赋值运算符 =
逗号运算符 ,

函数

函数就是封装了一段可被重复调用执行的代码块。通过此代码块可以实现大量代码的重复使用。

函数的使用

函数在使用时分为两步:声明函数调用函数

函数的声明

//声明函数
function 函数名() {
    //函数体代码
}
  • function是声明函数的关键字,必须小写
  • 由于函数一般是为了实现某个功能才定义的,所以通常我们将函数名命名为动词。
var fun = function() {
    //函数体
}
  • fun是变量名,不是函数名。
  • 函数表达式声明方式跟声明变量差不多,只不过变量里面存的是值,而函数表达式里存的是函数。
  • 函数表达式也可以进行传递参数。

函数的调用

//调用函数
函数名(); //通过调用函数名来执行函数体代码
  • f调用的时候千万不要忘记添加小括号。
  • 声明函数本身并不会执行代码,只有调用函数时才会执行函数体代码。

函数的封装

函数的封装是把一个或者多个功能通过函数的方式封装起来,对外只提供一个简单的函数接口。

函数参数

function 函数名(形参) {
	//函数体
}
函数名(实参);
  • 声明函数时,可以在函数名称后面的小括号中添加一些参数,这些参数被称为形参
  • 调用函数时,同样也需要传递相应的参数,这些参数被称为实参
  • 多个参数中间用逗号分隔。
  • 参数的作用是在函数内部某些值不能固定,我们可以通过参数在调用函数时传递不同的值进去。
参数个数 说明
实参个数等于形参个数 输出正确结果
实参个数多于形参个数 只取到形参的个数
实参个数小于形参个数多的形参定义为undefined,结果为NaN

函数返回值

  • return语句之后的代码不被执行。
  • return只能返回一个值。如果用逗号隔开多个值,以最后一个为准
  • 函数中如果没有return则返回undefined

arguments使用

  • 所有函数都内置了一个arguments对象,arguments对象中存储了传递的所有实参
  • arguments展示形式是一个伪数组,因此可以进行遍历。伪数组具有以下特点:
  • 具有length属性
  • 索引方式存储数据。
  • 不具有数组的push,pop等方法

作用域

  • 作用域:代码名字(变量)在某个范围内起作用和效果,目的是为了提高程序的可靠性,更重要的是减少命名冲突。
  • 作用域分为全局作用域局部作用域
  • 全局作用域:整个script标签或者是一个单独的js文件。
  • 局部作用域:在函数内部就是局部作用域,这个代码的名字只在函数内部起效果和作用。

变量的作用域

根据作用域的不同,变量可以分为全局变量局部变量

全局变量

在全局作用域下声明的变量叫做全局变量(在函数外部定义的变量)

  • 全局变量在代码的任何位置都可以使用。
  • 特殊情况下,在函数内不使用var声明的变量也是全局变量(不建议使用)。

局部变量

在局部作用域下声明的变量叫做局部变量(在函数内部定义的变量)

  • 局部变量只能在该函数内部使用。
  • 函数的形参实际上就是局部变量。

全局变量和局部变量的区别

  • 全局变量:在任何一个地方都可以使用,只有在浏览器关闭时才会被销毁,因此比较占内存
  • 局部变量:只在函数内部使用,当其所在的代码块被执行时,会被初始化;当代码块运行结束后,就会被销毁,因此更节省内存空间

作用域链

  • 只要是代码,就至少有一个作用域。
  • 写在函数内部的局部作用域。
  • 如果函数中还有函数,那么在这个作用域中就又可以诞生一个作用域。
  • 根据在内部函数可以访问外部函数变量的这种机制,用链式查找决定哪些数据能被内部函数访问,就称作作用域链

对象

  • 对象是一个具体的事物,看得见摸得着的事物。
  • 对象是一组无序的相关属性和方法的集合,所有的事物都是对象,例如字符串、数值、数组、函数等。
  • 对象是由属性方法组成的。属性是事物的特征。方法是事物的行为

对象的创建

  • 利用字面量创建对象。
  • 利用new Object创建对象。
  • 利用构造函数创建对象。

利用字面量创建对象

var obj = {
    name: 'Freedom',
    age: 18,
    sex: '男',
    say: function() {
        console.log('hello');
    }
}
  • 属性对象字面量:就是花括号{}里面包含了表达这个具体事物(对象)的属性和方法。
  • {}里面采取键值对的形式表示。相当于属性名值相当于属性值**,可以是任意类型的值(数字类型、字符串类型、布尔类型,函数类型等)。
  • 对象里面的属性调用:对象.属性名
  • 对象里面属性的另一种调用方式:对象['属性名'],注意方括号里面的属性必须加引号
  • 对象里面的方法调用:对象.方法名(),注意这个方法名字后面一定加括号

利用new Object创建对象

  • 跟数组的new Array()原理一致。
var obj = new Object();
obj.name = 'Freedom',
obj.age = 18,
obj.sex = '男',
obj.say = function() {
    console.log('hello');
}

利用构造函数创建对象

  • 构造函数是一种特殊的函数,主要用来初始化对象,即为对象成员变量赋初始值,它总与new运算符一起使用。我们可以把对象中一些公共的属性和方法抽取出来,然后封装到这个函数里面。
function 构造函数名() {
    this.属性 =;
    this.方法 = function() {}
}
new 构造函数名();
  • 构造函数名字首字母要大写
  • 构造函数不需要return就可以返回结果。
  • 调用构造函数必须使用new
  • 构造函数,抽象了对象的公共部分,封装到了函数里面,它泛指某一大类。
  • 创建对象,特指某一个,通过new关键字创建对象的过程我们也称为对象实例化

变量、属性、函数、方法的总结

  • 变量:单独声明赋值单独存在
  • 属性:对象里面的变量称为属性,不需要声明,用来描述该对象的特征。
  • 函数:单独存在,通过函数名()的方式就可以调用。
  • 方法:对象里面的函数称为方法,方法不需要声明,使用对象.方法名()的方式就可以调用,方法用来描述该对象的行为和功能。

遍历对象属性

  • for…in语句用于对数组或者对象的属性进行循环操作
var obj = {
    name: 'Freedom',
    age: 18,
    sex: '男',
    say: function() {
        console.log('hello');
    }
}

for (var key in obj) {
    console.log(key); //输出属性名
    console.log(obj[key]); //输出属性值
}

内置对象

  • javascript中的对象分为3种:自定义对象内置对象浏览器对象
  • 自定义对象内置对象是属于ECMAScript浏览器对象属于javascript独有的。
  • 内置对象就是指javascript语言自带的一些对象,这些对象供开发者使用,并提供了一些常用的或是最基本而必要的功能(属性和方法)。
  • javascript提供了多个内置对象:MathDateArrayString等。

Math对象

  • Math.PI:圆周率。
  • Math.floor():向下取整。
  • Math.ceil():向上取整。
  • Math.round():四舍五入,就近取整。
  • Math.abs():绝对值。
  • Math.max()/Math.min():求最大和最小值。
  • Math.random():随机数。

Date对象

  • Date对象和Math对象不一样,它是一个构造函数,需要实例化后才能使用
  • Date实例用来处理日期和时间

Date对象的实例化

var now = new Date();  //获取当前的时间
var dateTime = new Date('2019-5-1');  //获取参数里的时间

日期格式化的获取

方法名 说明
getFullYear() 获取当年
getMonth() 获取当月(0-11)
getDate() 获取当天日期
getDay() 获取星期几(周日0到周六6)
getHours() 获取当前小时
getMinutes() 获取当前分钟
getSeconds() 获取当前秒钟
getTime()/valueOf()/+new Date()/Date.now() 获取总的毫秒

Array对象

数组的创建

var arr = []; //空数组
var arr = new Array(); //空数组
var arr = new Array(2); //长度为2的数组
var arr = new Array(2,3); //长度为2,值为2,3的数组

数组的检测

参数 instanceof Array
Array.isArray(参数)  //只支持IE9以上版本

数组元素的添加删除

方法名 说明
push(parm) 末尾添加一个或多个元素,注意修改原数组
pop() 删除数组最后一个元素,把数组长度减1无参数、修改原数组
unshift(parm) 向数组的开头添加一个或更多元素,注意修改原数组
shift() 删除数组的第一个元素,数组长度减1无参数、修改原数组

数组的排序

方法名 说明
reverse() 颠倒数组中元素的顺序,无参数
sort() 对数组的元素进行排序

获取数组的索引

方法名 说明
indexOf() 数组中查找给定元素的第一个索引
lastIndexOf() 在数组中的最后一个的索引

数组转换为字符串

方法名 说明
toString() 把数组转换成字符串,逗号分隔每一项
join(‘分隔符’) 方法用于把数组中的所有元素转换为一个字符串

数组的改变

方法名 说明
concat() 连接两个或多个数组,不影响原数组
skice() 数组截取slice(begin,end)
splice() 数组删除splice(第几个开始,要删除个数)

字符串对象

  • 基本包装类型就是把简单数据类型包装成为复杂数据类型,这样基本数据类型就有了属性和方法。

  • 字符串的不可变指的是里面的不可变,虽然看上去可以改变内容,但其实是地址变了,内存中开辟了一个内存空间。

返回字符的位置

方法名 说明
indexOf(str,strPos) 返回指定内容在字符串中的位置,如果找不到就返回-1,开始的位置就是index索引号
lastIndexOf() 从后往前找,只找第一个匹配

根据位置返回字符

方法名 说明
charAt(index) 返回指定位置的字符(index字符串的索引号)
charCodeAt(index) 获取指定位置处字符的ASCII码(index索引号)
str[index] 获取指定位置处字符,只支持IE8以上

字符串的操作

方法名 说明
concat(str1,str2,str3…) concat()方法用于连接两个或多个字符串。拼接字符串,等效于+
substr(start,length) 从start位置开始(索引号),length取的个数
slice(start,end) 从start位置开始,截取到end位置,end取不到
substring(start,end) 从start位置开始,截取到end位置,end取不到,基本和slice相同,但是不接受负值
replace(‘替换前的字符’,‘替换后的字符’) 字符的替换
split(‘分隔符’) 字符转换为数组

Web API

  • API是给程序员提供的一种工具,以便能更轻松的实现想要完成的功能。

  • Web API是浏览器提供的一套操作浏览器功能和页面元素的API(BOM和DOM)。

DOM

  • 文档对象模型(DOM),是W3C组织推荐的处理可扩展标记语言(HTML或者XML)的标准编程接口。

DOM树

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xnt7nROG-1587566549149)(C:\Users\Administrator\Desktop\捕获.PNG)]

  • 文档:一个页面就是一个文档,DOM中使用document表示。
  • 元素:页面中的所有标签都是元素,DOM中使用element表示。
  • 节点:网页中的所有内容都是节点(标签、属性、文本、注释等),DOM中使用node表示。

获取页面元素

根据ID获取

  • document.getElementById('id'):通过id获取,返回一个元素对象。

根据标签名获取

  • document.getElementsByTagName('tag'):根据标签名获取,返回带有指定标签名的对象的集合。

通过HTML5新增的方法获取

  • document.getElementsByClassName('类名'):根据类名返回元素对象集合。
  • document.querySelector('选择器'):根据指定选择器返回第一个元素对象。
  • document.querySelectorAll('选择器'):根据指定选择器返回。

获取特殊元素

  • document.body:返回body元素对象。
  • document.documentElement:返回html元素对象。

操作元素

利用DOM操作元素里面的内容、属性等,可以该表网页内容、结构和样式。

  • element.innerText:从起始位置到终止位置的内容,但它去除html标签,同时空格和换行也会去掉。
  • element.innerHTML:起始位置到终止位置的全部内容,包括html标签,同时保留空格和换行。
  • 改变元素的属性:如srchrefalttitle等。
  • 改变表单元素的属性:如typevaluecheckedselecteddisabled等。
  • element.style:改变行内样式操作。
  • element.className:改变类名样式操作。
  • element.attr:获取元素本身自带的属性。
  • element.getAttribute(attr):主要获得程序员自定义的属性。
  • element.attr=value:设置内置属性值。
  • element.setAttribute(attr):主要设置自定义的属性。
  • element.removeAttribute(attr):移除属性。

节点操作

一般地,节点至少拥有nodeType(节点类型)、nodeName(节点名称)和nodeValue(节点值)这三个基本属性。

  • 元素节点nodeType为1。
  • 属性节点nodeType为2。
  • 文本节点nodeType为3(文本节点包含文字、空格、换行等)。

获取节点

  • node.parentNode:返回父节点。
  • parentNode.childNodes:返回包含指定节点的子节点的集合,该集合为即时更新的集合。
  • parentNode.children:获取所有的子元素节点。
  • parentNode.firstChild:返回第一个子节点,找不到则返回null。
  • parentNode.lastChild:返回最后一个子节点,找不到则返回null。
  • parentNode.firstElementChild:返回第一个子元素节点,找不到则返回null。只支持IE9以上。
  • parentNode.lastElementChild:返回最后一个子元素节点,找不到则返回null。只支持IE9以上。
  • parentNode.children[index]:返回子元素节点中的某个元素节点。
  • node.nextSibling:返回当前元素的下一个兄弟节点,找不到则返回null。包含所有的节点。
  • node.previousSibling:返回当前元素的上一个兄弟节点,找不到则返回null。包含所有的节点。
  • node.nextElementSibling:返回当前元素的下一个兄弟元素节点,找不到则返回null。只支持IE9以上。
  • node.previousElementSibling:返回当前元素的上一个兄弟元素节点,找不到则返回null。包含所有的节点。只支持IE9以上。

创建节点

  • document.createElement('tagName'):动态创建元素节点。

添加节点

  • node.appendChild(child):将一个节点添加到指定父节点的子节点列表末尾。
  • node.insertBefore(child,指定元素):将一个节点添加到父节点的指定子节点前面。
  • element.insertAdjacentHTML(position, text):将指定的文本解析为HTML,并将结果节点插入到DOM树中。
    • beforebegin: 元素自身的前面。
    • afterbegin: 插入元素内部的第一个子节点之前。
    • beforeend: 插入元素内部的最后一个子节点之后。
    • afterend: 元素自身的后面。

删除节点

  • node.removeChild(child):返回删除的节点。

补充:阻止链接跳转需要添加javascript:void(0)或者javascript:;

复制节点

  • node.cloneNode():返回调用该方法的节点的一个副本。

注意:如果括号参数为空或者为false,则是浅拷贝,即只克隆复制节点本身,不克隆里面的子节点;括号参数为true,则是深度拷贝,会复制节点本身以及里面所有的子节点。

三种动态创建元素区别

  • document.write()是直接将内容写入页面的内容流,但是文档流执行完毕,则它会导致页面全部重绘。
  • element.innerHTML()是将内容写入某个DOM节点,不会导致页面全部重绘。
  • element.innerHTML()创建多个元素效率更高(不要拼接字符串,采取数组形式拼接),结构稍微复杂。
  • document.creatElement()创建多个元素效率稍微低一点点,但是结构更清晰

总结:不同浏览器下,innerHTML效率要比createElement高。

事件

事件是由三部分组成:事件源事件类型事件处理程序

  • 事件源:事件被触发的对象。
  • 事件类型:如何触发。
  • 事件处理程序:通过一个函数赋值的方式。

常见的鼠标事件

鼠标事件 触发条件
onclick 鼠标点击左键触发
onmouseover 鼠标经过触发(不仅自身,子盒也会)
onmouseenter 鼠标经过触发(自身)
onmouseout 鼠标离开触发
onfocus 获得鼠标焦点触发
onblur 失去鼠标焦点触发
onmousemove 鼠标移动触发
onmouseup 鼠标弹起触发
onmousedown 鼠标按下触发

注册事件

  • 给元素添加事件,称为注册事件或者绑定事件

  • 注册事件有两种方式:传统方式方法监听注册方式

传统注册方式

  • 利用on开头的事件onclick。
  • <button onclick="alert("hi")"></button>
  • btn.onclick=function(){}
  • 特点:注册事件的唯一性。
  • 同一个元素同一个事件只能设置一个处理函数,最后注册的处理函数将会覆盖前面注册的处理函数。

方法监听注册方式

  • w3c标准推荐方式。
  • addEventListener()它是一个方法。
  • IE9之前的IE不支持此方法,可使用attachEvent()代替。
  • 特点:同一个元素同一个事件可以注册多个监听器。
  • 按注册顺序依次执行。
eventTarget.addEventListener(type, lstener[, useCapture]);

eventTarget.addEventListener()方法将指定的监听器注册到eventTarget(目标对象)上,当该对象触发指定的事件时,就会执行事件处理函数。

  • type:事件类型字符串,比如click、mouseover,注意这里不要带on。
  • listener:事件处理函数,事件发生时,会调用该监听函数。
  • useCapture:可选参数,是一个布尔值,默认是false。
eventTarget.attachEvent(eventNameWithOn, callback);

eventTarget.attachEvent()方法将指定的监听器注册到eventTarget(目标对象)上,当该对象触发指定的事件时,指定的回调函数就会被执行。

  • eventNameWithOn:事件类型字符串,比如click、mouseover,这里要带on。
  • callback:事件处理函数,当目标触发事件时回调函数被调用。

注册事件兼容性解决方案

function addEventListener(element, eventName, fn) {
    //判断当前浏览器是否支持addEventListener方法
    if (element.addEventListener) {
        element.addEventListener(eventName, fn);  //第三个参数 默认是false
    } else if (element.attachEvent) {
        element.attachEvent('on' + eventName, fn);
    } else {
        //相当于element.onclick = fn;
        element['on' + eventName] = fm;
    }
}

删除事件

传统注册方式

eventTarget.onclick = null;

方法监听注册方式

eventTarget.removeEventListener(type, listener[, useCapture]);
eventTarget.detachEvent(eventNameWithOn, callback);

删除事件兼容性解决方案

function removeEventListener(element, eventName, fn) {
    //判断当前浏览器是否支持removeEventListener方法
    if (element.removeEventListener) {
        element.removeEventListener(eventName, fn);  //第三个参数 默认是false
    } else if (element.detachEvent) {
        element.detachEvent('on' + eventName, fn);
    } else {
        element['on' + eventName] = null;
    }
}

事件流

事件流描述的是从页面中接收事件的顺序。

DOM事件流:事件发生时会在元素节点之间按照特定的顺序传播。

DOM事件流分为三个阶段:捕获阶段当前目标阶段冒泡阶段

  • 事件冒泡:IE最早提出,事件开始时由最具体的元素接收,然后逐级向上传播到DOM最顶层节点的过程。
  • 事件捕获:网景最早提出,由DOM最顶层节点开始,然后逐级向下传播到具体的元素接收的过程。

事件流的注意事项

  • js代码中只能执行捕获或者冒泡其中的一个阶段。
  • onclickattachEvent只能得到冒泡阶段。
  • addEventListener(type, listener[, useCapture])第三个参数如果是true,表示在事件捕获阶段调用事件处理程序;如果是false(不写默认就是false),表示在事件冒泡阶段调用事件处理程序。
  • 实际开发中很少使用事件捕获,更关注事件冒泡。
  • 有些事件是没有冒泡的,比如onblur、onfocus、onmouseenter、onmouseleave。

事件对象

事件对象:事件发生后,跟事件相关的一系列信息数据的集合都放到这个对象里面。它有很多属性和方法。

eventTarget.onclick = function(event) {
    //这个event就是事件对象,可以写成e或者evt
}
eventTarget.addEventListener('click', function(event) {
    //这个event就是事件对象,可以写成e或者evt
})
  • event是个形参,系统帮我们设定为事件对象,不需要传递实参过去。
  • 当我们注册事件时,event对象就会被系统自动创建,并以此传递给事件监听器(事件处理函数)。

事件对象的兼容性方案

  • 标准浏览器中是浏览器给方法传递的参数,只需要定义形参e就可以获取到。
  • 在IE6~8中,浏览器不会给方法传递参数,如果需要的话,需要到window.event中获取查找。
  • 解决方案:e = e || window.event();

事件对象的常见属性和方法

事件对象属性方法 说明
e.target 返回触发事件的对象(标准)
e.srcElement 返回触发事件的对象(非标准IE6~8使用)
e.type 返回事件的类型,比如click不带on
e.cancelBubble 该属性阻止冒泡(非标准IE6~8使用)
e.returnValue 该属性阻止默认事件(非标准IE6~8使用),比如不让链接跳转
e.preventDefault() 该方法阻止默认事件(标准),比如不让链接跳转
e.stopPropagation() 阻止冒泡(标准)
//阻止事件冒泡的兼容性解决方案
if (e && e.stopPropagation) {
    e.stopPropagation();
} else {
    window.event.cancelBubble = true;
}

事件委托

  • 事件委托:不是每个子节点单独设置事件监听器,而是事件监听器设置在其父节点上,然后利用冒泡原理影响设置每个子节点。
var ul = document.querySelector('ul');
ul.addEventListener('click', function(e) {
    e.target.style.backgroundColor = 'pink';
})

其它常见鼠标事件

禁止鼠标右键菜单

  • contextmenu主要控制应该何时显示上下文菜单,主要用于程序员取消默认的上下文菜单。
document.addEventListener('contextmenu', function(e) {
    e.preventDefault();
})

禁止鼠标选中

  • selectstart开始选中。
document.addEventListener('selectstart', function(e) {
    e.preventDefault();
})

鼠标事件对象

鼠标事件对象 说明
e.clientX 返回鼠标相对于浏览器窗口可视区的X坐标
e.clientY 返回鼠标相对于浏览器窗口可视区的Y坐标
e.pageX 返回鼠标相对于文档页面的X坐标IE9+支持
e.pageY 返回鼠标相对于文档页面的Y坐标IE9+支持
e.screenX 返回鼠标相对于电脑屏幕的X坐标
e.screenY 返回鼠标相对于电脑屏幕的Y坐标
e.stopPropagation() 阻止冒泡(标准)

常见的键盘事件

键盘事件

键盘事件 触发条件
onkeyup 某个键盘按键被松开时触发
onkeydown 某个键盘按键被按下时触发
onkeypress 某个键盘按键被按下时触发,但它不识别功能键(比如shift、ctrl)
  • 如果使用addEventListener,不需要添加on
  • 键盘事件的执行顺序:onkeydown -> onkeypress -> onkeyup

键盘事件对象

键盘事件对象属性 说明
keyCode 返回该键的ASCII值
  • onkeydownonkeyup不区分字母大小写,onkeypress区分字母大小写。
  • 更多的使用keydown和keyup,它能识别所有的键(包括功能键)。

BOM

BOM浏览器对象模型,它提供了独立于内容而与浏览器窗口进行交互的对象,其对象是window

DOM BOM
文档对象模型 浏览器对象模型
DOM就是把文档当做一个对象来看待 把浏览器当做一个对象来看待
DOM的顶级对象是document BOM的顶级对象是window
DOM主要是操作页面元素 BOM主要是浏览器窗口交互的一些对象
DOM是W3C标准规范 BOM是浏览器厂商在各自浏览器上定义的,兼容性较差

BOM的构成

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-n6sWTF6t-1587566549160)(C:\Users\Administrator\Desktop\捕获.PNG)]

  • window对象是浏览器的顶级对象,它具有双重角色。
  • window对象是js访问浏览器窗口的一个接口。
  • window对象是一个全局对象。定义在全局作用域中的变量、函数都会变成window对象的属性和方法。

window对象的常见事件

窗口加载事件

window.onload = function(){}
或者
window.addEventListener("load",function(){});

window.onload是窗口(页面)加载事件,当文档内容完全加载完成会触发改时间(包括图像、脚本文件、css文件等),就调用的处理函数。

  • 有了window.onload就可以把js代码写到页面元素的上方,因为onload是等页面内容全部加载完毕,再去执行处理函数。
  • window.onload传统注册事件方式只能写一次,如果有多个,会以最后一个window.onload为准。
  • 如果使用addEventListener则没有限制。
document.addEventListener('DOMContentLoaded',function(){});
  • DOMContentLoaded事件触发时,仅当DOM加载完成,不包括样式表,图片,flash等等。IE9以上才支持。

  • 如果页面的图片很多的话,从用户访问到onload触发可能需要较长的时间,交互效果就不能实现,必然影响用户的体验,此时用DOMContentLoaded事件比较合适。

调整窗口大小事件

window.onresize = function(){} window.addEventListener("resize",function(){});

window.onresize是调整窗口大小加载事件,当触发时就调用的处理函数。

  • 只要窗口大小发生像素变化,就会触发这个事件。
  • 经常利用这个事件完成响应式布局。window.innerWidth当前屏幕的宽度。

定时器

setTimeout()定时器

window.setTimeout(调用函数, [延迟的毫秒数]);

setTimeout()方法用于设置一个定时器,该定时器在定时器到期后执行调用函数。

  • window可以省略
  • 这个调用函数可以直接写函数,或者写函数名或者采取字符串’函数名()'三种形式。第三种不推荐。
  • 延迟的毫秒数省略默认是0,如果写,必须是毫秒
  • 因为定时器可能有很多,所以经常给定时器赋值一个标识符。

停止setTimeout()定时器

window.clearTimeout(timeoutID)

clearTimeout()方法取消了先前通过调用setTimeout()建立的定时器。

  • window可以省略
  • 里面的参数就是定时器的标志符

setInterval()定时器

window.setInterval(回调函数, [间隔的毫秒数]);

setInterval()方法重复调用一个函数,每隔这个事件,就去调用一次回调函数。

  • window可以省略
  • 这个调用函数可以直接写函数,或者写函数名或者采取字符串’函数名()'三种形式。第三种不推荐。
  • 间隔的毫秒数省略默认是0,如果写,必须是毫秒,表示每隔多少毫秒就自动调用这个函数。
  • 因为定时器可能有很多,所以经常给定时器赋值一个标识符。

停止setInterval()定时器

window.clearInterval(tintervalID)

clearInterval()方法取消了先前通过调用setInterval()建立的定时器。

  • window可以省略
  • 里面的参数就是定时器的标志符

this

this的指向在函数定义的时候是确定了的,只有函数执行的时候才能确定this到底指向谁,一般情况下this的最终指向的是那个调用它的对象

  • 全局作用域或者普通函数中this指向全局对象window(注意定时器里面的this指向window)。
  • 方法调用中谁调用this指向谁。
  • 构造函数中this指向构造函数的实例。

js执行队列

js是单线程

  • JavaScaript语言的一大特点就是单线程,也就是说,同一个时间只能做一件事。这是因为JavaScript这门脚本语言诞生的使命所致——JavaScript是为处理页面中用户的交互,以及操作DOM而诞生的。比如我们对某个DOM元素进行添加和删除操作,不能同时进行。应该先进行添加,之后再删除。

  • 单线程就意味着,所有任务需要排队,前一个任务结束,才会执行后一个任务。这样所导致的问题是:如果js执行的时间过长,这样就会造成页面的渲染不连贯,导致页面渲染加载阻塞的感觉。

同步和异步

  • 同步:前一个任务结束后再执行后一个任务,程序的执行顺序与任务的排列顺序是一致的、同步的。

  • 异步:你在做一件事情时,因为这件事情会花费很长时间,在做这件事的同时,你还可以去处理其他事情。

  • 同步任务都在主线程上执行,形成一个执行栈

  • js的异步是通过回调函数实现的。一般而言,异步有三种类型:普通事件资源加载定时器。异步任务相关回调函数添加到任务队列中(任务队列也称为消息队列)。

js执行机制

  • 先执行执行栈中的同步任务。

  • 异步任务(回调函数)放入任务队列中。

  • 一旦执行栈中的所有同步任务执行完毕,系统就会按次序读取任务队列中的异步任务,于是被读取的异步任务结束等待状态,进入执行栈,开始执行。

  • 由于主线程不断的重复获得任务、执行任务、再获取任务、再执行,所以这种机制被称为事件循环

Location对象

  • window对象给我们提供了一个location属性用于获取或设置窗体的URL,并且可以用于解析URL。因为这个属性返回的是一个对象,所以我们将这个属性称为location对象

URL

  • **统一资源定位符(URL)**是互联网上标准资源的地址。互联网上的每个文件都有一个唯一的URL,它包含的信息指出文件的位置以及浏览器应该怎么处理它。

  • URL的一般语法格式为:protocol://host[:port]/path/[?query]#fragment

组成 说明
protocol 通信协议常用的http,ftp,maito等
host 主机(域名)
port 端口号
path 路径,由零或多个"/"符号隔开的字符串,一般用来表示主机上的一个目录或文件地址
query 参数,以键值对的形式,通过&符号分割开来
fragment 片段,#后面内容,常见于链接

Location对象的属性

location对象属性 返回值
location.href 获取或者设置整个URL
location.host 返回主机(域名)
location.port 返回端口号
location.pathname 返回路径
location.search 返回参数
location.hash 返回片段

Location对象的方法

location对象方法 返回值
location.assign() 跟href一样,可以跳转页面(也称为重定向页面)
location.replace() 替换当前页面,因为不记录历史,所以不能后退页面
location.reload() 重新加载页面,相当于刷新按钮或者f5

navigator对象

  • navigator.useAgent返回由客户机发送服务器的user-agent头部的值。

history对象

  • window对象给我们提供了一个history对象,与浏览器历史记录进行交互。该对象包含用户(在浏览器窗口中)访问过的URL。
history对象方法 作用
history.back() 可以后退功能
history.forward() 前进功能
history.go(参数) 前进后退功能,参数如果是1,前进1个页面;如果是-1,后退1个页面

PC端网页特效

元素偏移量offset系列

offset属性可以动态的得到该元素的位置(偏移)、大小等

  • 获得元素距离带有定位父元素的位置。
  • 获得元素自身的大小(宽度高度)。
  • 返回的数值都不带单位。
offset系列属性 作用
element.offsetParent 返回作为该元素带有定位的父级元素,如果父级都没有定位,则返回body
element.offsetTop 返回元素相对带有定位父元素上方的偏移
element.offsetLeft 返回元素相对带有定位元素左边框的偏移
element.offsetWidth 返回自身包括padding、边框、内容区的宽度,返回数值不带单位
element.offsetHeight 返回自身包括padding、边框、内容区的高度,返回数值不带单位

offset与style的区别

  • offset可以得到任意样式表中的样式值;style只能得到行内样式表中的样式值。
  • offset系列获得的数值是没有单位的;style.width获得的是带有单位的字符串。
  • offsetWidth包含padding+border+width;style.width获得不包含padding和border的值。
  • offsetWidth等属性是只读属性,只能获取不能赋值;style.width是可读写属性,可以获取也可以赋值。
  • 获取元素大小位置,用offset更合适 给元素更改值,则需要用style改变。

元素可视区client系列

client属性可以动态的得到该元素的边框大小,元素大小等

client系列属性 作用
element.clientTop 返回元素上边框的大小
element.clientLeft 返回元素左边框的大小
element.clientWidth 返回自身包括padding、内容区的宽度,不含边框,返回数值不带单位
element.clientHeight 返回自身包括padding、内容区的高度,不含边框,返回数值不带单位

元素滚动scroll系列

scroll属性可以动态的得到该元素的大小、滚动距离等

scroll系列属性 作用
element.scrollTop 返回被卷去的上侧距离,返回数值不带单位
element.scrollLeft 返回被卷去的左侧距离,返回数值不带单位
element.scrollWidth 返回自身实际的宽度,不含边框,返回数值不带单位
element.scrollHeight 返回自身实际的的高度,不含边框,返回数值不带单位

页面被卷去的头部 兼容性解决方案

  • 声明了DTD,使用document.documentElement.scrollTop
  • 未声明DTD,使用document.body.scrollTop
  • 新方法window.pageYOffsetwindow.pageXOffset,IE9开始支持。
function getScroll() {
    return {
        left: window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft || 0,
        top: window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0
    };
}
//使用的时候 getScroll().left

三大系列总结

  • offset系列经常用于获得元素位置(offsetLeft、offsetTop)。
  • client系列经常用于获取元素大小(clientWidth、clientHeight)。
  • scroll系列经常用于获取滚动距离(scrollTop、scrollLeft)。
  • 元素被卷去的头部通过element.scrollTop获得,页面滚动的头部通过window.pageYOffset获得,页面滚动的左侧通过window.pageXOffset获得。

动画函数封装

//轮播图
function animate(obj, tatget, callback) {
    //清除之前的定时器
    clearInterval(obj.timer);
    
    //设置定时器
    obj.timer = setInterval(function{
        //缓慢原理
        var step = (target - obj.offsetLeft) / 10;
        //将步长值改为整数
        step = step > 0 ? Math.ceil(step) : Math.floor(step);
        
        if (obj.offsetLeft == target) {
            //停止动画
            clearInterval(obj.timer);
            //回调函数写到定时器结束里面
            if (callback) {
                callback();
            }
        }
        
        obj.style.left = obj.offsetLeft + step + 'px';
    }, 15);
}
//滚动条
function animate(obj, tatget, callback) {
    //清除之前的定时器
    clearInterval(obj.timer);
    
    //设置定时器
    obj.timer = setInterval(function{
        //缓慢原理
        var step = (target - window.pageYOffset) / 10;
        //将步长值改为整数
        step = step > 0 ? Math.ceil(step) : Math.floor(step);
        
        if (window.pageYOffset == target) {
            //停止动画
            clearInterval(obj.timer);
            //回调函数写到定时器结束里面
            callback && callback()
        }
        
        window.scroll(0, window.pageYOffset + step)
    }, 15);
}

移动端网页特效

触摸事件

触摸事件 作用
touchstart 手指触摸DOM元素事件
touchumove 手指在DOM元素身上移动事件
touchend 手指离开DOM元素事件

触摸事件对象

  • 触摸事件是一类描述手指在触摸平面(触摸屏、触摸板等)的状态变化的事件。这类事件用于描述一个或多个触电,使开发者可以检测触电的移动,触电的增加和减少,等等。

  • touchstart、touchmove、touchend三个事件都会各自有事件对象。

触摸列表 说明
touches 正在触摸屏幕的所有手指的一个列表
targetTouches 正在触摸当前DOM元素上的手指的一个列表
changeTouches 手指状态发生了改变的列表,从无到有,从有到无变化

classList属性

classList属性是HTML5新增的一个属性,返回元素的类名。但是IE10以上版本支持。该属性用于在元素中添加,移除及切换CSS类。

  • element.classList.add(className);:添加类。

  • element.classList.remove(className);:移除类。

  • element.classList.toggle(className);:切换类。

click延时解决方案

  • 移动端click事件会有300ms的延时,原因是移动端屏幕双击会缩放页面。

  • 禁用缩放。浏览器禁用默认的双击缩放行为并且去掉300ms的点击延迟。``

  • 利用touch事件封装事件解决300ms延迟。

//封装tap,解决click300ms延迟
function tap (obj, callback) {
    var isMove = false;
    var startTime = 0; //记录触摸时候的时间变量
    obj.addEventListener('touchstart', function(e) {
        startTime.Date.now(); //记录触摸时间
    });
    obj.addEventListener('touchmove', function(e) {
        isMove = true; //看看是否有滑动,有滑动算拖拽,不算点击
    });
        obj.addEventListener('touchend', function(e) {
        //如果手指触摸和离开时间小于150ms算点击
        if (!isMove && (Date.now() - startTime) < 150) {
            callback && callback(); //执行回调函数
        }
        isMove = false; //取反 重置
        startTime = 0;
    });
}
//调用
tap(div, function() {
    //执行代码
});

本地存储

本地存储特性

  • 数据存储在用户浏览器中。
  • 设置、读取方便、甚至页面刷新不丢失数据。
  • 容量较大,sessionStorage约5M、localStorage约20M。
  • 只能存储字符串,可以将对象JSON.stingfy()编码后存储。

window.sessionStorage

  • 生命周期为关闭浏览器窗口。
  • 在同一个窗口(页面)下数据可以共享。
  • 以键值对的形式存储使用。

sessionStorage.setItem(key,value);:存储数据。

sessionStorage.getItem(key);:获取数据。

sessionStorage.removeItem(key);:删除数据。

sessionStorage.clear();:删除所有数据。

window.localStorage

  • 生命周期永久生效,除非手动删除,否则关闭页面也会存在。
  • 可以多窗口(页面)共享(同一浏览器可以共享)。
  • 以键值对的形式存储使用。

localStorage.setItem(key,value);:存储数据。

localStorage.getItem(key);:获取数据。

localStorage.removeItem(key);:删除数据。

localStorage.clear();:删除所有数据。

发布了132 篇原创文章 · 获赞 12 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/JavaDestiny/article/details/105695292