
JavaScript知识回顾
本文最后更新于 2024-12-08,文章内容可能已经过时。
JavaScript
js
是运行在客户端(浏览器)
的编程语言
,可以在浏览器
中实现交互特效
,网页特效
,表单验证
等!
JavaScript特性
解释性语言
解释性语言
就是读一行解释一行
, 一般在开发JavaScript
代码时候,计算机是无法直接认识的
,需要经过编译或者解释
后才能让计算机正确执行代码
! 计算机只认识0101011001
这样的二进制数字
!
解释性语言:
会将编写好的代码一行一行解释翻译成浏览器所认识的代码
!编译性语言:
会将编写好的代码完整过一遍后生成翻译文件
,进行整体翻译
!
单线程
单线程
就是不能在同一个时间段内干多件事儿
,只能同一时间内做一件事儿
!
多线程
就是可以在同一事件内处理很多事务
!
JS三大部分
ECMAScript
和DOM
以及BOM
ECMAScript:
是一种规范
,用于制定js语法
和规则
,JavaScript
是在ECMA规范
上的一种实现
!
DOM:
是文档对象模型
,是w3c
的标准
,提供了关于操作html元素dom的API方法
!
BOM:
是浏览器对象模型
,是每个浏览器内部
的一个实现
,提供对浏览器操作的API方法
!
ECMAScript
ECMAScript
是JavaScript
一套标准规范,
ECMA
会制定出方案
结果,JS
对方案进行的一个功能实现!
例如:
循环 判断 变量声明 函数声明
等基本语法!
字面量
字面量
表示声明值的一部分
,根据值的类型
,有不同类型的字面量
!
var age = 15;
则15
为数字字面量
!
var name = "张三";
则张三
为字符串字面量
!
变量
变量(容器):
它可以将不同数据类型的值
,存放
到一个变量(容器)
当中!
变量就是在程序中用来表示存储数据的!
声明变量
声明变量的方式有三种,分别为
var
let
和const
!
这里以
var
关键字举例说明:
var
是一种声明变量的关键字
,定义某个变量时
,必须加入关键字进行声明
,此处用来表示定义存储变量
!
var 变量声明关键字!
name 变量名!
= "张三"; 对变量名进行赋值操作,并存储数据!
三者声明变量区别
var
是属于早期的一种声明变量
的一种方式,其中存在众多问题,例如变量提升
,变量污染
,重复定义
等 !
变量提升
:js引擎
会在解析js代码
时,将变量声明提取到作用域的最顶端
,且初始值为undefind
!
变量污染
:var
没有块级作用域
,在块级作用域中定义的变量
,依旧可以在上级或全局作用域中访问
!
重复声明
:var
在同一个作用域
内可以重复声明一个变量
,会导致后面的变量值覆盖已有的变量值
!
变量提升
变量提升
,就是js引擎
在解析代码
时,会将声明的所有变量提升在作用域顶部
,这就意味着在变量赋值之前
依旧可以访问变量,只不过该变量的值为undefind
!变量污染
变量污染
, 就是var
是属于函数作用域
,不属于块级作用域
,块级作用域
包括(if for switch
),这意味着,在块级内部定义的变量
,在块级之外
依旧可以访问
!重复定义声明
重复定义声明
, 在代码中可以在同一个作用域下重复定义一个已存在声明变量的值
!
let
和 const
这两种
声明方式
,是es6提出的标准
,它们的出现就是为了解决var
声明变量时所遗漏的一些问题 !
let
:- 不能在
同一个作用域内重复定义变量
! - 无法
在变量赋值前进行变量访问
,不存在变量提升
! - 属于
块级作用域
,在块级之外无法访问,且不会对环境变量造成污染!
- 不能在
const
:与
let
关键字基本一致,则区别是,const
是用来定义常量
!- 常量在
声明变量时
,必须有初始值
! - 且
一旦被赋值,则无法在改变值
!
- 常量在
变量的本质
定义变量的本质,就是
在内存中开辟一个空间
,将变量值存储内存空间中
!其
变量名
则为内存空间
的一个命名方式
,通过命名
可以获取对应空间中的存放数据
!
命名规范
不能以关键字进行命名
,例如let const if for
等语法关键字!只能用下划线 字母 数字 $部分组成
,不能以数字作为开头
!首字母不能大写,驼峰命名,例如
noProblem
!
数据类型
在
js
中数据类型
为弱类型
,弱类型
就是根据赋值后
来判定该值类型
为某一个具体类型
!
基本数据类型
基本类型
: (字符串
,布尔值
,null
,undefind
,symbol
,bigInt
)
引用数据类型
引用数据类型
: 也是复杂类型
(Array_数组 Object_对象 Function_函数
)
引用数据类型
:在内存中会开辟一个新的空间
用来存放这个地址
,并将这个地址指向声明变量的变量名!
区别
基本数据类型
:- 存放在
栈内存中
,在内存中存放的是值
,可以直接对值进行操作,和对比
!
- 存放在
引用数据类型
:- 存放在
堆内存中
,在内存中会存放引用类型的地址
,并将地址指向声明变量的变量名
!
- 存放在
运算符
运算符
包含(算数运算符
和比较运算符
以及赋值运算符
和逻辑运算符
)
算数运算符:+ - * / %(取模),算数优先级,先乘除后加减,若有括号先算括号里的表达式! %(取模) 就是两者相除剩余的余数!
比较运算符: 分为弱类型判断(== !=) 和 强类型判断(=== !==) 以及大小数值比较 (<= >=)!
赋值运算符:
分为正常赋值( a = b ) 和 逻辑赋值( ??=, ||=, &&=, )
弱类型和强类型比较
弱类型:(== !=) 使用 弱类型判断 时,会做类型隐士转换,比如(“1” == 1)返回为 true,原因是,会将字符串1转换为 number类型后在进行判断!
强类型:(=== !==) 使用 强类型判断 时,类型不会做转换,("1"=== 1) 返回为 false,两者类型不一致,则结果不同!
逻辑赋值
逻辑与赋值
(Logical AND Assignment)- &&=
语法
:x &&= y
解释
:如果x
为真
(truthy),则将y
赋值给x
。
逻辑或赋值
(Logical OR Assignment)- ||=
语法
:x ||= y
解释
:如果x
为假
(falsy),则将y
赋值给x
。
逻辑空赋值
(Logical Nullish Assignment)- ??=
语法
:x ??= y
解释
:如果x
为null
或undefined
,则将y
赋值给x
。
类型转换
类型转换,通常就是将一种基本类型,转换成另一个基本类型,常用在
字符串转数字
的场景!
转换 字符串 为数字
作为
"-"
号运算符时,例如:
条件判断
条件判断
:就是根据表达式
返回(true/false
)分别进入不同分支代码
块进行运行结果!
if语句
语法
switch语句
循环语句
冒泡排序
函数
函数的作用
就是将一些共用的业务逻辑进行抽离
, 在不同的业务场景下进行函数调用处理
!
封装冒泡函数案例
在
函数体内
中包含,参数对象(arguments)
,动态绑定对象(this),
返回值(return)
,作用域
,以及原型链
等相关知识!
函数声明方式
命名函数
匿名函数
匿名函数
,就是没有命名的函数
,常见的应用场景有,立即执行函数
,回调函数
,闭包
,事件绑定函数
!
立即执行函数:
回调函数:
闭包:
事件绑定:
立即执行函数
立即执行函数
,就是创建一个独立作用域
的可立即执行
的函数体
!
注意: 立即执行函数,代码结束位置需要加入";"号
,确保上一个代码段执行完毕
!
参数传递
参数
分为:形参
和实惨
!
形参: 是在声明函数的时候,定义的参数叫形参!
实参: 在函数调用时,传递的参数可称为实参数,实际传递的参数!
在函数内部
,有一个arguments
参数对象,改对象包含一组参数列表!
arguments
有自己的length
,但是不是真正的数组,无法使用数组的方法
来处理参数列表对象
!
返回值
返回值,
就是函数在执行完毕时,向外部返回的一个结果!
使用
return
关键字可以返回一个结果!
作用域
作用域
就是一个变量可访问范围,
通常在创建一个函数时
,内部会有自己的作用域
,除了自身作用域以外
,还会包含父级作用域
!
局部作用域
:- 在
函数内部
,或者块级儿内部
定义的变量
,且该变量仅能在局部作用域内生效!
- 在
全局作用域
:- 在
全局代码
中定义的变量,可供全局任何地方访问
的变量就是属于全局作用域
!
- 在
作用域链
js引擎
在解析函数
时,会创建内部作用域
,也会有一个父级作用域parentScope!
当在内部作用域内访问一个变量
时,且该变量未在当前作用域中定义
,则会向父级作用域中查找
,直到全局作用域获取到为止
若都没有
,则报错is not defind!
this动态绑定
this
是函数体内
特有的动态绑定对象
,根据函数调用情况
,返回不同this对象
!
this
有四种绑定
方式分别为:默认绑定
隐式绑定
显示绑定
new绑定
!
默认绑定
:- 在
全局中定义函数
时,并在全局中调用该函数
时,this
会指向 window 全局
对象!
- 在
隐式绑定
:- 当
函数作为某个对象中的方法
时,通过对象的方式来调用该函数
,这时,this
会指向该对象
!
- 当
显示绑定
:- 在
js
中有三种方法可以修改函数的this指向
,分别是apply call bind
,该方法是函数中特有的,用来修改函数
中的this
指向!
- 在
new绑定
:new
是创建构造函数
的关键字,创建构造函数时会创建一个空对象
,并将函数的this指向这个空对象
!
字符串
字符串就是被双引号引住的值,例如
"张三", "描述"
!
常用的方法
字符串的长度
:length
: "hello".length
查找字符串
:charAt(index)
: 指定索引位置,返回索引位置所对应的字符!indexOf(substr, start)
: 检索字符串,根据指定字符
,返回该字符的索引位置
!lastIndexOf(substr, start)
: 返回子字符串最后一次出现的位置
。includes(searchString, position)
:判断
字符串是否包含指定的子字符串
,返回布尔值
。startsWith(searchString, position)
:判断
字符串是否以指定的子字符串开始
。endsWith(searchString, length)
:判断
字符串是否以指定的子字符串结束
。
字符串提取
:slice(start, end)
: 根据开始索引和结束索引,对字符串进行截取,不包含最后索引值!。substring(start, end)
: 与slice
相似,不支持负数!substr(start, length)
: 从索引开始位置截取,到指定长度!
字符串替换
:replace(searchValue, replaceValue)
: 替换字符串中匹配的值
(只替换第一个匹配项
)。replaceAll(searchValue, replaceValue)
: 替换字符串中所有匹配的值
。
大小写转换
:toUpperCase()
: 将字符串转换为大写
。toLowerCase()
: 将字符串转换为小写
。
去空白字符
:trim()
: 去除字符串两端
的空白字符。trimStart()
: 去除字符串开头
的空白字符。trimEnd()
: 去除字符串结尾
的空白字符。
分割字符串
split
: 根据指定字符,将字符串进行分割,返回一个分割后的数组列表!
连接字符串
:concat(str1, str2, ...)
: 连接两个或多个字符串
。
重复字符串
repeat(count)
: 重复字符串指定的次数。
数组
数组是js中数据结构存储之一
,它可以存储任意类型的值
,包括基本类型
,引用类型
,Set,
Map
,等数据结构
!
操作数组方法
unshift
: 在数组的第一项添加
元素!shift
:删除
数组的第一项,并返回删除的元素
!push
: 在数组的最后一项添加
元素!pop
:删除
数组最后一项,并返回删除的元素
!indexOf
:检索
数组中的某一项,若找到则返回该元素在数组中的索引位置
,否则返回-1
!slice
:截取
根据起始索引
和结束索引
位置,对数组进行截取,不包含结束索引位置
!splice
:添加
、删除
或替换
数组中的元素,会改变原始数组
!语法
:array.splice(start, deleteCount, item1, item2, ..., itemX)
start
: 必需。指定开始修改数组的索引位置。如果为负数
,则从数组末尾开始计算
。deleteCount
: 可选。指定要删除的元素数量。如果省略或大于等于
从start
到数组末尾的元素数量
,则删除从 start 到数组末尾的所有元素
。item1, item2, ..., itemX:
可选。要添加到数组中的新元素
,从start
位置开始插入。
includes
: 判断数组中是否包含该元素
,返回Boolean
!concat
: 将两个数组合并
,返回一个新的数组长度!join
: 将数组通过某个字符分割成字符串
!
数组遍历方法
for循环
:forEach
:forEach
无法通过break
或return
提前终止循环
。for...in
:主要用于
迭代对象的可枚举属性
!for...of
:循环用于遍历
可迭代对象
(如数组、字符串、Map、Set
等)的元素。
ES6新增的迭代方法
map
:对数组元素进行
逻辑处理
后,返回一个新的数组
,不会影响原来的数组结构!filter
:对数组元素进行过滤, 返回一个
过滤后新的数组结构
! 会过滤掉undefind
和null
的数据!some
:判断该数组中,是否有
某些元素
满足条件,满足则返回true
, 否则返回false
;every
:判断数组中
所有元素
满足该条件时,返回true
, 否则返回false
;find
:返回满足条件的那一条数据!
findIndex
:返回满足条件的那一条数据的
index
索引值!
对象
在
js
中对象
也是一种数据存储结构
,它是以键值对
形式存储数据
,并通过键来获取值
!
对象的操作
根据
key
来获取value
:设置对象属性值:
遍历对象属性
内置对象
内置对象
就是js中预制的对象
,像Date日期
Math数学
RegExp正则
对象等 !
全局对象
Object
: 是所有对象的基类
,包含对象的一些操作方法
,例如对象属性是否可枚举,可写
,以及一些属性判断
等方法!Function
: 是所有函数的基类
,提供了一些方法,如call(), apply(), bind()
等。Array
: 用于创建数组对象
,包含一些数组的方法push(), pop(), slice(), splice()
!String
: 用于创建字符串对象
,包含一些字符串相关的方法,如slice(), replace(), toUpperCase()
等!Number
: 用于创建数字对象
,包含一些数字处理相关的方法,如toFixed() toPrecision()
!Boolean
: 用于创建布尔对象
,提供布尔值相关的方法。Date
: 用于处理日期和时间
,提供日期和时间相关的方法,如getFullYear(), getMonth(), getDate()
等!RegExp
: 用于创建正则表达式对象
,提供正则表达式相关的方法,如test(), exec()
等!
错误对象
Error
: 所有错误对象的基类
。TypeError
: 表示类型错误
。ReferenceError
: 表示引用错误
。
数学对象
Math
: 提供数学常数和函数,如Math.PI
,Math.sin()
,Math.cos()
,Math.random()
等。
Math.abs()
: 绝对值,所有负数
转换为正数
!Math.max() Math.min()
: 返回参数中最大值(max)
或最小值(min)
!Math.floor() Math.ceil()
: 向下取整(floor
) 和 向上取整(ceil
)!Math.random()
: 随机数 默认 >= 0 小于1
JSON对象
JSON
: 提供将对象转换为 JSON 字符串
和将 JSON 字符串解析为对象
的方法,如JSON.stringify()
,JSON.parse()!
DOM
DOM
(文档对象模型)document
主要用来操作 html dom元素
!
例如:
对 元素的创建
删除
以及 元素属性的添加删除
等一系列有关操作!
DOM 不属于javascript中的范畴,是独立的,是w3c标准提供的对html元素一系列操作的接口(api)!
文档中对应的属性
document
: 获取整个html
文档!- 获取文档中的父节点或子节点
parentNode
: 获取元素的父节点
!childNodes
: 获取子节点
!sibling
: 获取同级
节点!
获取元素节点属性
通过
nodeType
属性可以获取元素节点所对应的属性常量值
:
属性 |
数值 |
描述 |
---|---|---|
文档节点(document ) |
9 |
Node.DOCUMENT_NODE |
元素节点(element ) |
1 |
Node.ELEMENT_NODE |
属性节点(attribute ) |
2 |
Node.ATTRIBUTE_NODE |
文本节点(text ) |
3 |
Node.TEXT_NODE |
文档片段(DocumentFragment ) |
11 |
Node.DOCUMENT_FRAGMENT_NODE |
获取元素的方法
根据元素标签
获取
指定
元素标签
返回一组符合元素标签的元素节点集合[HTMLCollection[div]]
!可以
实时获取元素的变化
,若没有符合
的元素,则返回一个空的集合
!
获取元素集合中某个元素
根据className
获取
根据 id
获取
使用query
选择器
接受一个
css选择器
,返回第一个符合的元素节点
!
使用queryAll
选择器
与
querySelector
类似,返回的是一个NodeList元素节点集合
!
创建元素与属性
创建和删除元素
使用
createElement
方法来创建
一个元素标签
!
创建元素属性
使用
createdAttribute
方法来创建
一个元素属性
,并返回一个元素节点
!使用
setAttributeNode
给元素设置属性
!
使用
setAttribute
和getAttribute
来设置元素的属性
和获取元素的属性
!
使用
removeAttribute
可以删除指定的属性!
追加子元素
使用
appendChild
在父元素
节点内部元素之后添加子元素
节点!
使用
insertBefore
在父元素
节点内部元素之前添加子元素
节点!
Element元素属性
元素属性
就是,可通过Element对象
直接获取或设置对应的属性内容
!
属性 | 描述 | 获取方式 |
---|---|---|
id |
获取元素属性id |
el.id |
className |
获取元素属性的class |
el.className |
classList |
获取元素属性的class 集合 |
el.classList |
innerText |
设置 或获取 元素节点的内容content |
el.innerText 获取 / el.innerText = '新的内容' |
innerHtml |
设置 或获取 元素节点中的html元素内容 |
el.innerHtml 获取 / el.innerHtml = '<p>新的内容</p>' |
添加或删除class
属性
add
属性可以添加
一个class
属性,remove
可以删除
一个class
属性!
contains
属性可以判断该元素中的class属性列表中是否包含,指定class选择器
!
toggle
如果class列表中不存在,则添加,否则删除
!
innerHTML属性
innerHTML
可以在页面中添加元素标签以及内容!
当
循环追加多个标签
时,存在性能问题
,导致页面渲染缓慢
!拼接字符串会引起渲染性能问题!
处理
性能问题
,可以将添加的元素放在数组当
中,通过join
的方法,将数组转换为字符串
,最后赋值与innerHTML元素
!
相对于
createElement
方法创建元素
,innerHTML
采用数组方式
来生成元素
时,其效率更高
!
获取元素的位置
包含
元素的宽高
,网页可见宽高
以及body的宽高
,用来配合元素在页面中的位置计算
!
元素偏移量(offset)
offset
系列
offset(偏移量):
获取
元素的自身的宽高
还有获取当前
元素的距离定位的父元素距离位置!
常用的属性
属性 | 描述 |
---|---|
el.offsetParent |
获取带有定位(绝对定位 和 相对定位)的父元素 ,如果没有定位 ,则获取body ! |
el.offsetLeft |
获取元素距离带有定位的父元素的左侧距离 |
el.offsetTop |
获取元素距离带有定位的父元素的顶部距离 |
el.offsetHeight |
获取元素自身的高度 ,内边距 边框 以及内容区的高度 ! |
el.offsetWidth |
获取元素自身的宽度 ,内边距 边框 以及内容区的宽度 ! |
offsetParent: 带有定位的父元素,没有则获取 body!
parentNode: 不管父元素有没有定位,都是最近一层上级元素!
offset
和 style
的区别
offset:
是只读
属性,无法进行赋值,只能用来获取元素的相关属性!
style:
是行内样式
,只能获取和修改元素的行内样式
!
获取在盒子内部的x
和y
坐标
拖动元素案例
innerX
和innerY
是鼠标
在box元素内部
触发事件时到左侧的一个距离
!
move
触发移动事件
时,需要重新计算
出,box
元素的距离body top
和left
值!
计算规则
:(pageX, pageY or clientX ,clientY )
获取鼠标
距离左侧
和顶部
的坐标值(x,y)
减去
,鼠标
距离box元素
的内部坐标值(x,y)!
内部鼠标距离元素 left 和 top 的距离,通过 pageX - offsetLeft 和 pageY - offsetTop!
client系列
获取元素的
边框大小
,以及元素的大小
!
属性 | 描述 |
---|---|
el.clientLeft |
返回左边框 的大小! |
el.clientTop |
返回上边框 的大小! |
el.clientWidth |
返回元素的宽度,包含 padding 和 内容的宽度 ,不包含border ! |
el.clientHeight |
返回元素的高度,包含 padding 和 内容的高度 ,不包含border ! |
scroll系列
可以获取元素滚动时的距离!
属性 | 描述 |
---|---|
e.scrollTop |
返回上层被滚动隐藏元素的距离 ! |
e.scrollLeft |
返回左侧被滚动隐藏元素的距离 ! |
e.scrollWidth |
返回自身实际的宽度,不包含border ! |
e.scrollHeight |
返回自身实际的高度,不包含border ! |
在窗口下滚动被卷去的元素距离
window.pageXOffset:
获取在窗口内滚动
被卷去的左侧距离!
window.pageYOffset:
获取在窗口内滚动
被卷去的顶部距离
!
兼容问题 : >= ie9
否则使用document.body.scrollTop
如果是在
元素内部
滚动,请使用el.scrollTop
和el.scrollLeft!
滚动案例
总结
offset
和client
以及scroll
都可以获取元素本身的宽高
,除了offset
获取宽高包含boder
以外,其它两个都不包含border
!
设置css
样式
使用
setAttribute
来设置样式:使用
style
属性来设置:使用
cssText
属性来设置:
事件操作
事件
就是一种在网页元素中的操作行为
,例如鼠标事件
,滚动事件, 键盘事件
等!
鼠标事件:
常见的有点击事件
,滚轮事件
,以及鼠标移入移出的事件
!
键盘事件:
就是键盘的按键触发事件
的一种行为操作
!
以上就是一个
按钮点击事件
的案例!
注册事件
注册事件
,就是给元素添加事件
的方式,一种是传统方式注册
,一种是对事件的一个监听
!
传统方式注册
在元素上
通过事件绑定属性
来注册一个事件:在j
s代码中通过元素对象
,获取事件属性
并赋值与函数来注册事件:
传统事件注册
,只能给元素绑定一个事件
,若出现多次绑定
的情况,则后面的绑定事件会覆盖之前的
绑定!
事件监听器
事件监听器
就是通过addEventListener
该方法来注册一个事件
!
addEventListener:
该方法存在兼容性问题,IE9之前
不支持,添加事件需使用attachEvent(非标准,生产环境不推荐使用);
参数:
事件监听的类型(
type
):click mouseover mouseout
等...,这里不需要写on
!事件监听的回调函数(
callback
): 当触发事件
时,该回调函数被执行
!
给某个元素
添加事件监听
!这里同一个元素
可以添加多个事件监听,且依次执行
!
attachEvent事件注册
事件类型
,需要补充on语法!
删除事件
删除事件 使用该方法 removeEventListener,可以对事件进行解绑和删除!
传统
事件绑定
的删除方式
:使用
监听器
绑定事件后进行解绑
:使用
attchEvent
方式绑定的事件进行解绑:
DOM事件流
事件流
就是一个传播过程
,当给元素绑定事件时
会有以下流程:
捕获阶段
: 由根元素
到子元素
的一个过程,直到发现被绑定事件的子元素
!
冒泡阶段
: 由子元素
到根元素
的一个过程,直到根元素
为止!
事件捕获
addEventListerer
第三个参数为Boolean
,为true
时,则为捕获阶段
,为false
时或默认
时,则为冒泡阶段
!
捕获阶段:
事件的执行顺序
,会从根元素
开始, 从外
而内
,进行事件触发执行
!
冒泡阶段
冒泡阶段
: 事件的执行顺序
,会从子元素
开始,从内
而外
,进行事件触发执行
!
设置冒泡
行为,第三个参数为false
时,或者默认不传
时,则为冒泡
!
事件对象
事件对象(event)
,就是每一个事件类型
所触发后
产生的一个对象
!
鼠标事件
触发后,事件对象会包含该鼠标对象
的信息!
键盘事件
触发后,事件对象会包含改键盘对象
的信息!
event
是一个对象
,包含了,当前触发事件
的一系列信息!
注意: event
在 ie678
里存在兼容问题!
可以通过window.event
来获取!
this
绑定对象 与 el.target
对象的区别
this
是绑定对象
,是当前绑定事件
的元素对象
!
el.target
是获取返回触发事件的元素对象
信息!
el.target
是有兼容问题,在ie678
下可以通过el.srcElement
来获取
阻止默认事件
阻止默认事件(preventDefault方法)
,默认事件就是某个元素在触发事件时,一些默认行为操作
!
表单提交 button type="submit",提交后,会默认提交以及刷新浏览器的行为!
preventDefault 兼容问题:
ie678
请使用:e.returnValue!
这是一个属性不是一个方法!
阻止冒泡事件
冒泡事件
,从子元素开始,向上层逐个事件触发
,为了保证事件触发的单一行
,需要进行冒泡行为阻止
!
stopPropagation
该方法,可以帮我们阻止事件传播过程
!
事件委托
事件委托
,就是不在子元素上进行一个一个事件绑定
,通过事件传播
的行为,将事件绑定到父元素上
,来操作子元素
!
事件对象中常见的属性和方法
鼠标事件
事件类型
有很多种,鼠标移入元素 移出元素 点击元素 以及 触发焦点 和 失去焦点事件等类型
!
事件类型 | 事件描述 |
---|---|
onclick |
鼠标点击左键 事件 |
onmouseenter |
鼠标移入自身元素时 触发事件,如果自身元素下有子元素 ,则移入子元素时,不触发 ,因为没有冒泡 ! |
onmouseleave |
鼠标移出 事件,与enter相似 |
onmouseover |
鼠标经过该元素时频繁 触发事件,如果自身元素下有子元素 ,则鼠标移入时依旧触发事件 ! |
onmouseout |
鼠标移出 事件,与over相似 |
onfocus |
鼠标触发焦点 事件 |
onblur |
鼠标失去焦点 事件 |
onmousemove |
鼠标移动 事件 |
onmouseup |
鼠标按键抬起 触发事件 |
onmousedown |
鼠标按键按下 触发事件 |
contentmenu |
鼠标右键按下 触发事件 |
selectstart |
鼠标开始选择 时触发事件 |
ondbclick |
鼠标双击 时触发事件操作 |
禁止鼠标右键菜单
禁止文字选择
鼠标事件对象
鼠标事件对象
event
, 当鼠标事件触发
时,产生的MouseEvent事件对象
,包含关于鼠标相关属性信息!
比如,鼠标的
坐标位置
等相关信息!
属性 | 描述 |
---|---|
e.clientX |
当前鼠标指针 相对于 body 可视窗口 x 坐标 ! |
e.clientY |
当前鼠标指针 相对于 body 可视窗口 y 坐标 ! |
e.pageX |
当前鼠标指针 相对于 document(文档 包含滚动区域 的 x 坐标! |
e.pageY |
当前鼠标指针 相对于 document(文档) 包含滚动区域 的 y 坐标! |
e.screenX |
当前元素 相对于 电脑屏幕 x 坐标 ! |
e.screenY |
当前元素 相对于 电脑屏幕 y 坐标 ! |
e.offsetX |
当前鼠标指针 相对于当前元素 的left 距离! |
e.offsetY |
当前鼠标指针 相对于当前元素 的top 距离 ! |
鼠标事件跟随案例
案例
键盘事件
事件 | 描述 |
---|---|
onkeyup |
按键抬起 时触发事件 |
onkeydown |
按键按下 时触发事件 不区分大小写! |
onkeypress |
按键按下 时触发事件 不识别 ctrl shift 箭头 ,区分大小写! |
键盘事件对象
event键盘事件对象
,就是当触发键盘行为操作
时,会生成一个键盘对象(keybordEvent
)
根据keyCode
来判断对应的按键值
keyCode
返回一个ASCLL码值
,每一个按键,且对应一个相应的值!
表单事件
事件 | 描述 |
---|---|
submit |
当表单元素提交 时,触发该事件! |
reset |
当表单元素被重置 时,触发该事件! |
change |
当表单元素发生改变 的时候触发该事件! |
input |
当表单元素输入内容 时触发该事件! |
窗口事件
事件 | 描述 |
---|---|
load |
当页面以及所有资源加载完毕 时触发该事件! |
unload |
当用户离开页面 时触发该事件! |
scroll |
当页面滚动时 触发该事件! |
resize |
当窗口或者元素大小发生改变 时触发该事件! |
触摸事件
事件 | 描述 |
---|---|
touchstart |
当用户开始触摸屏幕 时触发。 |
touchmove |
当用户触摸屏幕并移动 时触发。 |
touchend |
当用户停止触摸屏幕 时触发 |
touchcancel |
当触摸被中断 时触发 |
拖拽事件
拖拽元素时,需要
给拖拽元素增加拖拽属性
,才可以对元素进行拖拽
行为!
draggable="true"
事件 | 描述 |
---|---|
dragstart |
当用户开始拖动元素 时触发。此事件通常用于初始化拖拽数据,如设置 dataTransfer 对象的数据类型和数据值 |
drag |
当元素被拖动时持续触发 。此事件可以用于实时更新拖拽 过程中的状态,例如显示拖拽进度 。 |
dragenter |
当被拖动的元素进入目标元素时触发 。此事件用于确定目标元素是否可以接受拖拽 的数据 |
dragover |
当被拖动的元素在目标元素上移动时持续触发 。此事件用于更新拖拽过程中的视觉效果 ,例如改变目标元素 的样式 |
dragleave |
当被拖动的元素离开目标元素 时触发。此事件用于重置目标元素的样式 |
drop |
当用户释放鼠标按钮并完成拖放操作时触发 。此事件用于处理拖放的数据 ,例如将拖动的元素插入到目标元素 中 |
dragend |
当拖拽操作结束 时触发,无论是否成功放下 。此事件用于清理拖拽过程中的状态 ,例如重置拖拽元素 的样式 |
拖拽案例
事件顺序
: 拖拽事件有特定的触发顺序,通常是dragstart -> drag -> dragenter -> dragover -> drop -> dragend
。阻止默认行为
: 在dragover
和drop
事件中,需要调用event.preventDefault()
来阻止默认的拖拽
行为(如打开文件
)。数据传递
: 在dragstart
事件中,可以使用dataTransfer.setData
方法传递数据
,在drop
事件中可以使用dataTransfer.getData
方法获取数据
浏览器兼容性
: 虽然大多数现代浏览器
BOM
BOM(浏览器对象模型) 主要是浏览器内一些相关的api操作!
例如: 对 浏览器窗口对一些操作,如果页面跳转历史记录(history), location, navgitor,本地存储(sessionStorage localStorage cookie)等!
BOM缺乏标准规范
,JS的标准
规范是由ECMA
实现的,DOM 的标准
规范是由W3C
实现的,而BOM
最早是由Netscape浏览器标准
的一部分!
BOM
是浏览器厂商自己
定义的标准,兼容性比较差
!
window全局对象
在
浏览器
中,window
是一个顶层对象
也是全局对象
,可以通过该对象来访问一些基本的webapi
!所有定义在
全局的变量和函数
,都会被绑定在顶层对象window
中!
注意:
window
对象中有一个特殊的属性
,window.name
,该name
属性,是在一开始初始化
时,就已经存在的属性
,且默认值为" "
!
window常见的事件
页面加载事件
onload
: 当页面所有资源以及dom元素加载完毕
时调用该回调函数!DOMContentLoaded
: 当所有dom元素加载完毕
时调用该回调函数,不包含图片 flash 以及css样式表资源
!ie9+ 支持!
- 好处是,
不用等待其他外部引用资源加载完毕
时,处理逻辑操作,当外部资源体积大且加载缓慢
,则只需要处理dom时
可以使用该事件!
pageshow
: 在页面显示时加载事件,无论页面是否缓存!a 连接跳转
返回当前页时触发事件刷新页面
或者强制刷新
触发事件pageshow
会在load 事件后触发
e.persisted
可以判断该是否在缓存中的页面中触发!
火狐浏览器
,在跳转页面并通过浏览记录返回时
,会对原有的页面进行缓存
,缓存后的页面不会触发onload事件
!
窗口以及元素大小监听事件
resize事件,
当窗口
或者元素大小
发生变化时,触发该事件!
定时器
定时器
就是根据指定时间
去执行一段逻辑
!
setTimeOut
根据
指定时间
,在时间结束后
,执行回调
函数!单位为
毫秒
!第一个参数,
回调函数
,第二个参数,指定的时间单位(毫秒)
!
setInterval
根据
指定时间
,循环间隔执行回调
函数!单位为
毫秒
!第一个参数,
回调函数
,第二个参数,指定的时间单位(毫秒)
!
清除定时器
清除定时器
,在一定时机内
,将定时器进行清除
,结束回调函数的执行行为!
clearInterval
是清除定时器(Interval)
的一个函数,且参数为定时器所返回的id值
!
clearTimeout
是清除定时器(Timeout)
的一个函数,且参数为定时器所返回的id值
!
倒计时案例
时间单位换算
1秒 = 1000毫秒
1分钟 = 60秒 * 1000毫秒
1小时 = 60分钟 * 60秒 * 1000毫秒
1天 = 24小时 * 60分钟 * 60秒 * 1000毫秒
1周 = 7天 * 24小时 * 60分钟 * 60秒 * 1000毫秒
1月 = 30天 * 7天 * 24小时 * 60分钟 * 60秒 * 1000毫秒
1年 = 365天 * 30天 * 7天 * 24小时 * 60分钟 * 60秒 * 1000毫秒
小时: parseInt(时间戳 / 60 / 60 % 24)
分钟: parseInt(时间戳 / 60 % 60)
秒: parseInt(时间戳 % 60)
js执行机制
js 语言
是单线程
语言,在代码执行
时只能同时处理一件事情
!在
js 代码
中,如果遇到代码运行比较耗时
的逻辑,按照单线程
的管理,只有等待耗时任务完成
时,才能执行下一段
逻辑!因此,为此解决问题,则执
行代码逻辑
分为,同步代码
执行,和异步代码
执行!
同步任务(代码)
同步任务:
代码依次执行
,只有等待上一步代码执行完毕后才会执行下一步代码
,且不能同时
执行其他任务代码
!
异步任务(代码)
异步任务:
代码依次执行
,但是执行代码时,遇到异步任务
代码,会将异步任务回调函数
存放到任务队列
当中,不影响其它代码执行
,当需要异步任务代码执行
时,会从队列中按次序获取相应的回调函数并执行
!
定时器(setTimeout setInterval)
,事件(click mousemove...) 以及网络请求(ajax)
等都属于异步任务
!
执行栈:
此处,会执行同步任务代码
!
任务队列: 此处,会存放异步任务回调函数!
fun
回调函数 |console.log(3)
执行顺序,
首先
执行执行栈
中的同步任务
,当遇到异步任务
时,会将回调函数放入任务队列
当中,然后继续执行同步任务
,至到同步任务执行完毕
后,才会从任务队列中执行异步任务回调函数
!
事件循环
在
执行代码
时,遇到异步代码
,会将异步回调函数存放到任务队列
当中,但是在存放过程
中,有一个异步任务队列处理程序
,主要来判断
,该异步任务回调函数是否需要存放到任务队列当中
!
执行栈
->异步任务处理
->任务队列(执行回调函数后调用)
->执行栈
如上图,
点击事件
,经过异步任务队列处理程序
,不会立即
存放到任务队列
当中,只有点击
的时候,会将异步回调函数添加到任务队列中并执行异步回调函数,执行完毕后,并清空任务队列中的回调函数,待下次新的异步回调函数进入!
当
执行栈
中的同步代码执行完毕
时,执行栈
会反复查看异步任务队列
中,是否有可执行的异步回调函数来执行!
location
location
主要用来处理和解析网页域名路径(URL)!
域名(URL)组成
http://127.0.0.1:5500/dom.html?id=1234591283
协议
://ip 地址
:port
(端口)?query
(查询参数)
常见的属性
属性 | 描述 |
---|---|
location.href |
获取 和设置 整个URL路径 |
location.host |
返回主机的域名 |
location.part |
返回端口号 ,未写返回空的字符串 |
location.pathname |
返回路径 |
location.search |
返回参数 |
location.hash |
返回 hash 路径 # 号后面的锚点 |
常见的方法
方法 | 描述 |
---|---|
location.assign(url) |
与 href 一样,可以跳转页面,会有浏览历史记录 ! |
location.replace(url) |
替换当前页面,不会被浏览历史记录 ! |
location.reload(true) |
重新加载页面 ,相当于 f5 刷新,如果参数 为true , 则为强制刷新 ctrl+f5 |
navigator
navigator
包含了浏览器的一些基本信息
,常用的属性有userAgent,
主要用来获取当前平台的信息
,可以判断是PC
还是移动端H5
!
history
history 对象
,主要用来和浏览器历史记录进行交互
,可以实现浏览记录前进后退跳转
的基本功能 !
back()
:后退
功能!forword()
:前进
功能!go(-1):
跳转
功能,参数如果是1
这是前进
功能,如果是-1
这是后退
功能!
本地存储
本地存储
是一种存储数据的一种方式
,平时我们的数据
在刷新浏览器
或者关闭浏览器
以及标签页
时,数据都会消失
,通过
本地存储
的方式,将数据
存储到浏览器本地内存
中,这样就不会因刷新
或者关闭
的情况下丢失数据
了!
本地存储
,有三种
方式,sessionStorage(会话存储)
localStorage(本地存储)
cookie
!
特性 | sessionStorage |
localStorage |
cooKie |
---|---|---|---|
存储容量 |
5M |
5M |
4kb |
声明周期 |
会话窗口关闭(浏览器或标签页) |
持久存储,至到手动清除 |
设置过期时间 (持久存储),会话结束(cookie) |
与服务器交互 |
不会自动发送到服务器 | 不会自动发送到服务器 | 每次http请求 都会自动发送到服务器 |
用途 |
主要用于在单个会话中存储临时数据 |
主要用于在客户端存储大量数据,如用户设置、缓存数据等 |
主要用于存储用户状态信息,如登录状态、用户偏好设置 等 |
安全性 |
不支持 HttpOnly ,安全性较低 |
不支持 HttpOnly ,安全性较低 |
可以设置 HttpOnly 和 Secure 属性,增加安全性 |
API |
提供简单的 setItem 和 getItem 方法 |
提供简单的 setItem 和 getItem 方法 | 需要使用 document.cookie 进行操作 |
sessonStorage
会话存储
,存储大小5M
,不支持httpOnly
,浏览器窗口关闭
或标签页关闭
时会话结束
!
api | 参数 | 描述 |
---|---|---|
sessionStorage.setItem() |
setItem(key,value) |
设置 存储数据,key为键 ,value为值 ! |
sessionStorage.getItem() |
getItem(key) |
根据key获取存储数据 ,key为键 ! |
sessionStorage.removeItem() |
removeItem(key) |
根据key删除存储数据 ,key为键 ! |
sessionStorage.clear() |
clear() |
清空 存储数据! |
localStorage
本地存储
,存储大小5M(因每个浏览器不一致,大小或更多,且通常最大为5M,最小为4M)
,不支持httpOnly
,手动清除
!
api | 参数 | 描述 |
---|---|---|
localStorage.setItem() |
setItem(key,value) |
设置 存储数据,key为键 ,value为值 ! |
localStorage.getItem() |
getItem(key) |
根据key获取存储数据 ,key为键 ! |
localStorage.removeItem() |
removeItem(key) |
根据key删除存储数据 ,key为键 ! |
localStorage.clear() |
clear() |
清空 存储数据! |
cookie
Cookie
是一种小型文本文件
,由服务器发送到用户的浏览器
,并在用户下次访问
同一网站时由浏览器自动发送回服务器
。Cookie
主要用于存储用户状态信息,如登录状态、用户偏好
设置等。
存储方式
每个
Cookie
都有名称、值、路径、域、过期时间
等属性。
cookie封装
设置 Cookie
获取cookie
删除cookie