JS API
一、变量声明用let or const
-
变量声明优先使用const,const语义化更好
-
const声明的变量值不能更改,且声明时需要初始化
-
对于引用数据类型(数组、对象等),const声明的变量,里面存的不是值,而是地址,可以追加,但是不能改为其他的
-
对象和数组尽量用const来声明
二、API的作用和分类
作用:使用JS去操作html和浏览器
分类:DOM(文档对象模型)、BOM(浏览器对象模型)
- DOM:操作网页内容,开发网页特效和实现用户交互
- DOM树:将HTML文档以树状结构直观的表现出来,直接体现标签与标签之间的关系
三、DOM对象
-
DOM对象:浏览器根据html标签生成的js对象
-
所有的标签属性都可以在这个对象上面找到
-
修改这个对象的属性会自动映射到标签身上
-
-
DOM的核心思想:把网页内容当做对象来处理
-
document对象
-
是DOM里提供的一个最大的对象
-
它提供的方法和属性都是用来访问和操作网页内容的——>如document.write()
-
网页的所有内容都在document里
-
四、DOM元素获取及操作
4.1 根据CSS选择器来获取DOM元素
// 传入参数为字符串,返回值为object,未匹配到,返回null
const box = document.querySelector('CSS选择器') // 获取第一个匹配的元素
// 传入参数为字符串,返回值为多个object的伪数组,未匹配到,返回null
// 伪数组:没有pop()、push()等方法,有长度和索引号
const box = document.querySelectorAll('.box') // 获取多个个匹配的元素
for(let i = 0; i < lis.length; i++){ // 伪数组只能通过遍历来修改样式
console.log(lis[i])
}
// 其他获取DOM元素的方法
const li = document.getElementById('nav') // 通过id获取
const li1 = document.getElementsByTagName('div') // 通过标签获取
const li2 = document.getElementsByClassName('box') // 通过类名获取
4.2 操作DOM元素内容
DOM元素.innerText:
- 将文本内容更新/添加到任意标签位置
- 显示纯文本、不解析标签
DOM元素.innerHTML:
- 将文本内容更新/添加到任意标签位置
- 会不解析标签
// DOM元素.innerText
const box = document.querySelector('.box')
box.innerText = '你好'
// DOM元素.innerHTML
const box = document.querySelector('.box')
box.innerHTML = '<strong>我们都好</strong>'
4.3 操作元素属性
- 常用属性修改:通过js修改/设置标签属性,如src、href、title等
// 格式
const img = document.querySelector('img')
img.src = address[number]
- 控制样式属性修改:
(1)通过style属性操作CSS
const box = document.querySelector('.box')
box.style.width = '300px'
box.style.backgroundColor = 'hotpink'
(2)通过类名className操作CSS——>会直接覆盖以前的类名
// 格式如下,其中active是CSS中的一个类
DOM元素.className = 'active'
(3)通过classList操作类控制CSS——>由于className会覆盖以前的类名,因此用classList追加或者删除类(重点)
// 追加
DOM元素.classList.add('类名')
// 删除
DOM元素.classList.remove('类名')
// 切换,有这个类就删除,没有这个类就加上
DOM元素.classList.toggle('类名')
- 操作表单样式属性:
// 获取表单元素的值
DOM元素.value
// 获取表单元素的类型
DOM元素.type
// 通过js改变复选框状态,DOM属性.checked为true时勾选
<body>
<input type="checkbox" name="" id="">
<script>
const cbox = document.querySelector('input')
cbox.checked = true // 只接受bool值
</script>
</body>
// 通过js改变按钮状态,DOM属性.disabled为true时禁用按钮
<body>
<button disabled="disabled">获取验证码</button>
<script>
const but = document.querySelector('button')
but.disabled = false
</script>
</body>
</html>
自定义属性:
<!--定义格式:data-属性名 如下 -->
<body>
<div data-id="1" data-spm="小李"></div>
<div data-id="2" data-spm="小王"></div>
<script>
const first = document.querySelector('div')
console.log(first.dataset) <!--获取自定义属性的方法 -->
console.log(first.dataset.id)
console.log(first.dataset.spm)
</script>
</body>
五、定时器-间歇函数
开启定时器格式: setInterval(函数名,间隔时间(单位/ms))
关闭定时器格式: clearInterval(定时器编号)
<script>
function fn(){
console.log('2秒执行一次');
}
let timer1 = setInterval(fn,2000) // 开启定时器
clearInterval(timer1) // 关闭定时器
</script>
六、事件监听
事件: 编程系统里发生的动作或发生的事情,如用户在页面上点击一个按钮;
事件监听: 让程序检测是否有事件发生,一旦事件发生,就调用一个函数做出响应,也叫事件绑定或者注册事件。
语法: DOM元素对象.addEventListener(‘事件类型’,要执行的函数)
事件监听三要素:
- 事件源:DOM元素对象
- 事件类型:以什么方式触发,如鼠标单击click
- 事件调用函数:要做什么事
<!-- -->
body>
<button>点击</button>
<script>
const btn = document.querySelector('button')
btn.addEventListener('click',function(){
alert('你好呀~')
})
</script>
</body>
七、鼠标事件
<script>
const box = document.querySelector('.box')
box.addEventListener('click',function(){ // 点击
console.log('testing click');
})
box.addEventListener('mouseenter',function(){ // 鼠标进入
console.log('testing enter');
})
box.addEventListener('mouseleave',function(){ // 鼠标离开
console.log('testing leave');
})
</script>
八、焦点事件
<script>
const input = document.querySelector('input')
input.addEventListener('focus',function(){ // 获得焦点
console.log('有焦点事件触发了...');
})
input.addEventListener('blur',function(){ // 失去焦点
console.log('焦点失去了了...');
})
</script>
九、键盘事件
<script>
const input = document.querySelector('input')
input.addEventListener('keydown',function(){ // 键盘按下
console.log('键盘按下了……')
})
input.addEventListener('keyup',function(){ // 键盘抬起
console.log('键盘松开了……')
})
input.addEventListener('input',function(){ // 文本事件,用户输入事件
console.log(input.value)
})
</script>
十、事件对象
事件对象: 保存事件触发时的相关信息
使用场景:
- 可以判断用户按下了哪个键,如检测回车键Enter
- 可以判断用户点击了哪个元素,从而做出相应的操作
获取事件对象:
- 在事件绑定的回调函数中的第一个参数就是事件对象
- 一般命名为e、ev、e
<script>
const input = document.querySelector('input')
input.addEventListener('keyup',function(e){
console.log(e) // e为事件对象,打印e
})
</script>
事件对象常用属性:
- type:获取当前事件的类型
- clientX/clientY:获取光标相对于浏览器可见窗口左上角的位置
- offsetX/offsetY:获取光标相对于当前DOM元素左上角的位置
- key:获取用户按下键盘的值
note: 字符串.trim() 去除字符串两侧的空格
十一、环境对象、回调函数
环境对象:指的是函数内部的特殊变量this,它代表着当前函数运行时所处的环境
作用: 弄清this的指向,让代码更简洁
特点:
- 函数的调用方式不同,this指代的对象也不同
- 判断this指向的粗略规则——>谁调用,this就指向谁
- 直接调用函数,相当于是Window.函数,因此this指向Window
<body>
<button>提交</button>
<script>
function fn(){
console.log(this) // this 指向window
}
fn()
const btn = document.querySelector('button')
btn.addEventListener('click',function(){
console.log(this) // this 指向button
this.style.color = 'hotpink'
})
</script>
</body>
回调函数: 若一个函数被当做参数传递给另一个函数,那么这个函数就是回调函数
常见的使用场景:
// 以下fn()都是回调函数
setInterval(fn(){},1000)
clearInterval(fn(){},1000)
DOM元素.addEventListener('click',function(){})
十二、事件流
事件流: 事件完整执行过程中的流动路径
事件流的两个阶段:
- 捕获阶段——>从父到子
- 冒泡阶段——>从子到父
事件捕获: 从DOM的根元素开始去执行对应的事件
代码: DOM元素.addEventListener(事件类型,事件处理函数,是否使用捕获机制)
- 上述代码第三个参数为true时,表示捕获阶段触发;默认是冒泡阶段,即默认值是false
事件冒泡:当一个元素触发事件之后,会依次向上调用所有元素的同名事件
事件冒泡是默认存在的,要阻止事件冒泡,使用 e.stopPropagation()
阻止默认行为,使用e.preventDefault()
<html lang="en">
<head>
<style>
.father{
width: 200px;
height: 200px;
background-color: blue;
}
.son{
width: 100px;
height: 100px;
background-color: hotpink;
}
</style>
</head>
<body>
<div class="father">
<div class="son"></div>
</div>
<script>
const father = document.querySelector('.father')
const son = document.querySelector('.son')
document.addEventListener('click',function(){
alert('这是爷爷级……')
}) // 加上第三个参数true时,为捕获阶段
father.addEventListener('click',function(){
alert('这是爸爸级……')
}) // 加上第三个参数true时,为捕获阶段
son.addEventListener('click',function(e){
alert('这是儿子级……')
e.stopPropagation() // 阻止冒泡
}) // 加上第三个参数true时,为捕获阶段
</script>
</body>
</html>
两种注册事件的区别:
传统on注册(L0)
- 同一个对象,后面注册的事件会覆盖前面注册的(同一个事件)
- 直接使用null覆盖就可以实现事件的解绑
- 只有冒泡阶段
事件监听注册(L2)
- 语法:addEventListener(事件类型,事件处理函数,是否使用捕获)
- 后面注册的事件不会覆盖前面注册的(同一个事件)
- 可以通过第三个参数确定实在冒泡或者捕获阶段执行
- 必须使用removeEventListener(事件类型,事件处理函数,是否使用捕获)解绑事件
- 匿名函数无法解绑
鼠标经过事件区别:
-
mouseover 和 mouseout 会有冒泡效果
-
mouseenter 和 mouseleave 不会有冒泡效果
十三、事件委托
原理: 事件委托利用事件冒泡的特点——>给父元素注册事件时,当我们触发子元素的时候,会冒泡到父元素上,从而触发父元素的事件
优点: 减少注册次数,提高程序性能
实现: 事件对象(e).target.tagName 可以获得真正触发事件的元素
十四、其他事件
14.1 页面加载事件(load、DOMContentLoade)
- 监听页面所有资源加载完毕——>给window添加load事件 代码:window.addEventListener(‘load’,function(){// 执行的操作})
- 也可以针对某个某个DOM属性添加load事件
- 监听页面DOM加载完毕——>给document添加DOMContentLoaded事件 代码:document.addEventListener(‘DOMContentLoaded’,function(){// 执行的操作})
- 无需等待样式表、图像完全加载
// script写到head标签里时,需要给window添加load事件
<head>
<script>
window.addEventListener('load',function(){ // load
const btn = document.querySelector('button')
btn.addEventListener('click',function(){
alert('你好呀~')
})
})
</script>
</head>
14.2 页面滚动事件
<script>
window.addEventListener('scroll',function(){ // 给整个窗口添加滚动事件
console.log('我滚动了')
})
</script>
scrollLeft 和 scrollTop(属性):
- 获取被卷去的大小
- 获取元素内容往左、往上滚出去看不到的距离
- 这两个值是可读写的
语法:DOM元素.scrollLeft DOM元素.scrollTop
获取html元素的方法: document.documentElement
获取整个页面向上滚动的像素:document.documentElement.scrollTop
// 给DOM元素注册返回顶部事件
<script>
const backtop = document.querySelector('.xtx-elevator #backTop')
backtop.addEventListener('click',function(){
// document.documentElement.scrollTop = 0 // 方法一
window.scrollTo(0, 0) // 方法二
})
</script>
14.3 页面尺寸事件
// 检测页面尺寸的变化
<script>
window.addEventListener('resize',function(){
console.log('页面尺寸变化了');
})
</script>
client系列获取元素宽高: clientWidth、clientHeight(不包含border、margin、滚动条等,即可见部分的宽高)
// 获取页面的宽高
<script>
window.addEventListener('resize',function(){
let w = document.documentElement.clientWidth
let h = document.documentElement.clientHeight
console.log(w,h)
})
</script>
offset系列获取元素相对于位置的尺寸:
获取宽高:
- 获取元素自身的宽高——包括元素自身设置的宽高、padding、border(client系列不包含边框)
- offsetWidth和offsetHeight
- 获取得到的是数值,不是字符串
- 获取的是可视宽高,盒子隐藏时为0
获取位置:
- offsetLeft和offsetTop,只读属性
- 获取元素距离自己定位父级元素的左、上距离
获取位置:
DOM元素.getBoundingClientRect() 该方法返回元素的大小及相对于可视窗口的位置
总结:
属性 | 作用 | 说明 |
---|---|---|
scrollLeft和scrollTop | 被卷去的头部和左侧 | 配合页面滚动来用,可读写 |
clientWidth和clientHeight | 获取元素的宽度和高度 | 不包含border、margin、滚动条,用于获取DOM元素大小,只读 |
offsetWidth和offsetHeight | 获取元素的宽度和高度 | 包含border、padding、滚动条,只读 |
offsetLeft和offsetTop | 获取元素距离自己定位父级 元素的左、上距离 | 获取元素位置时使用,只读 |
十五、日期对象
15.1 实例化
使用new关键字,如下:
<script>
// 获取当前时间
const date = new Date()
console.log(date)
// 指定时间
const date1 = new Date('2023-5-17 08:30:00')
console.log(date1)
</script>
15.2 日期对象方法
方法 | 作用 | 说明 |
---|---|---|
getFullYear() | 获得年份 | 获取四位年份 |
getMonth() | 获得月份 | 取值为0-11 |
getDate() | 获取月份中的每一天 | 不同月份取值也不同 |
getDay() | 获取星期 | 取值为0-6 |
getHours() | 获取小时 | 取值为0-23 |
getMinuters() | 获取分钟 | 取值为0-59 |
getSeconds() | 获取秒 | 取值为0-59 |
格式化输出时间:
<script>
const div = document.querySelector('div')
const date = new Date()
div.innerHTML = date.toLocaleDateString() // 2023/5/12
div.innerHTML = date.toDateString() // Fri May 12 2023
div.innerHTML = date.toLocaleString() // 2023/5/12 14:53:56
div.innerHTML = date.toLocaleTimeString() // 14:54:45
</script>
15.3 时间戳
时间戳是指1970年01月01日00时00分00秒起至现在的毫秒数,是一种特殊的计算时间方式
// 获取时间戳的三种方式
<script>
// 方式一:getTime()
const date = new Date()
console.log(date.getTime())
// 方式二:+new Date()
console.log(+new Date())
// 方式二:Date.now()
console.log(Date.now())
</script>
十六、节点操作
DOM节点: DOM树里每一个内容都称之为节点
节点类型: 元素节点(所有标签-如div,p html根节点)、属性节点(所有属性 如herf,class)、文本节点(所有的文本)
16.1 查找节点(通过关系查找)
关键词 | 用法 | 描述 |
---|---|---|
parentNode | DOM元素.parentNode | 获取距离节点最近的父节点 |
children | DOM元素.children | 获取该节点的所有子节点 |
nextElementSibling | DOM元素.nextElementSibling | 获取该节点兄弟节点中的下一个 |
previousElementSibling | DOM元素.previousElementSibling | 获取该节点兄弟节点中的上一个 |
16.2 增加节点
创建元素节点 document.createElement(‘标签名’)
插入元素节点
-
父节点元素.appendChild(创建的节点) 在父节点的最后一个子节点之后插入创建的节点
-
父节点元素.insertBefore(创建的节点,插入的位置) 在父节点的某一个子节点之前插入该创建的节点
克隆节点: DOM元素.cloneNode(布尔值)
cloneNode会克隆出一个跟原标签一样的元素,括号内传入布尔值
-
若为true,则代表克隆时会包含后代节点一起克隆
-
若为false,则代表克隆时不包含后代节点
-
默认为false
16.3 删除节点
语法: 父元素.removeChild(要删除的元素)
- 在JavaScript原生DOM操作中,要删除元素必须通过父元素删除
- 若不存在父子关系则删除不成功
- 删除节点和隐藏节点(display:none),不一样,隐藏的节点还存在的,但是删除则不存在了
十七、window对象
17.1 BOM
BOM浏览器对象模型
- window对象是一个全局对象,即它是JavaScript中的顶级对象
- document、alert()、console.log()这些都是window的属性,基本上BOM的属性和方法都是window的
- 所有通过var定义在全局作用域中的变量、函数都会变成window对象的属性和方法
- window对象下的属性和方法调用时可以省略window
17.2 定时器——延迟函数
语法: setTimeout(回调函数,执行的毫秒数) 回调函数只执行一次,可以理解为把一段代码延迟执行。
清除延迟函数:
let timer = setTimeout(回调函数,执行的毫秒数)
clearTimeout(timer)
- 延时器需要等待,所以后面的代码先执行
- 每一次调用延时函数都会产生一个新的延时器
17.3 JS执行机制及事件循环
同步任务:立即执行的任务,JS中同步任务都在主线程上执行,形成一个执行栈
异步任务:JS通过回调函数实现,异步任务会添加到任务队列中。JS中异步任务有以下三种类型:
- 普通事件,如click、resize等
- 资源加载,如load、error等
- 定时器,setInterval、setTimeout等
JS执行机制:
-
先执行执行栈中的同步任务;
-
异步任务放入任务队列中;
-
一旦执行栈中的所有同步任务执行完毕,系统就会按次序读取任务队列中的异步任务,于是被读取的异步任务结束等待状态,进入执行栈,开始执行。
事件循环:
在程序本身运行的主线程会形成一个"执行栈",除此之外,设立一个"任务队列",每当有异步任务完成之后,就会在"任务队列"中放置一个事件,当"执行栈"所有的任务都完成之后,会去"任务队列"中看有没有事件,有的话就放到"执行栈"中执行。这个过程会不断重复,这种机制就被称为**事件循环(Event Loop)**机制。
17.4 location对象
location.href 获取完整的URL地址,对其赋值可实现地址的跳转
location.hash 获取地址中携带的哈希值,符号#后面的部分
location.search 获取地址中携带的参数,符号?后面的部分
location.reload() 刷新当前的页面,传入参数为true时为强制刷新,相当于**(Ctrl+F5)**
17.5 navigator对象和history对象
navigator.userAgent 获取设备信息
history.back()、 history.go(-1): 后退
history.forward()、 history.go(1): 前进
// 检测userAgent
!(function(){
const userAgent = navigator.userAgent
console.log(userAgent);
// 验证是否为Android或iPhone
const android = userAgent.match(/(Android);?[\s\/]+([\d.]+)?/)
const iphone = userAgent.match(/(iPhone\sOS)\s([\d_]+)/)
console.log(android,iphone)
// 如果是Android或iPhone,则跳转至移动端
if(android || iphone){
location.href = 'http://m.itcast.cn'
}
})()
十八、本地存储
18.1 本地存储介绍
-
数据存储在用户浏览器中
-
设置、读取方便,页面刷新数据也不会丢失
-
容量较大,sessionStorage和localStorage分别有5M左右
18.2 本地存储分类
localStorage:只能存储字符串
<script>
// 存储数据localStorage.setItem('键','值') 一定要使用引号
localStorage.setItem('uname','RYH') // 有该键就修改值,没有就添加
localStorage.setItem('age',18)
// 取数据localStorage.getItem('键')
console.log(localStorage.getItem('uname'))
console.log(localStorage.getItem('age'))
// 删除数据 localStorage.removeItem('键')
localStorage.removeItem('uname')
</script>
sessionStorage使用方法和localStorage一样,但是有以下特点:
-
生命周期为关闭浏览器之前
-
在同一个窗口(页面)下数据可以共享
-
以键值对的形式存储使用
18.3 存储复杂数据类型
<script>
const obj = {
ID : '1234',
uname : 'WXR',
age : 22,
gender : '男',
}
// 存 将复杂数据类型转换为JSON格式
localStorage.setItem('obj',JSON.stringify(obj))
// 取 先将数据取出来,然后再转换为对象格式
const str = localStorage.getItem('obj')
console.log(JSON.parse(str))
</script>
十九、正则表达式
19.1 定义及作用
正则表达式是用于匹配字符串中字符组合的模式。
作用:
-
表单验证——匹配
-
过滤敏感词——替换
-
字符串中提取感兴趣的部分——提取
19.2 语法
- 定义规则 const 变量名 = /被检测的字符串/
- 检测——test(): 找到返回true,否则返回false exec():找到返回一个数组,否则返回null
<script>
const str = 'This is a beautiful world!'
const reg = /beautiful/
console.log(reg.test(str))
console.log(reg.exec(str))
</script>
19.3 元字符
元字符: 具有一些特殊含义的字符,可以极大提高灵活性和强大的匹配功能
边界符: 用于提示字符所处的位置
边界符 | 说明 |
---|---|
^ | 表示匹配行首的文本(以谁开始) |
$ | 表示匹配行尾的文本(以谁结束) |
量词: 设定某个模式出现的次数
量词 | 说明 |
---|---|
* | 重复次数大于等于0 |
+ | 重复次数大于等于1 |
? | 重复次数为0或1 |
{n} | 重复n次 |
{n,} | 重复次数大于等于n |
{n,m} | 重复次数n到m |
字符类:
(1) [ ]匹配字符集合 只要后面的字符串中有一个字符在[ ]中就返回true
/ ^[0-9]/:用于匹配数字
/^[a-z]/:用于匹配小写字母
/^[A-Z]/:用于匹配大写字母
/^[0-9a-zA-Z]/:用于匹配只含数字、小写字母、大写字母的字符串
(2) [ ]里的^表示取反 如/[A-Z]$/ 表示除了大写字母以外的其他字符
(3) .(点)匹配除换行符以外的所有字符
(4) 预定义:指某些常见模式的简写方式
预定类 | 说明 |
---|---|
\d | 匹配0-9之间的任一数字,相当于[0-9] |
\D | 匹配0-9以外的字符,相当于[^0-9] |
\w | 匹配任意的字母、数字和下划线,相当于[A-Za-z0-9_] |
\W | 除所有字母、数字和下划线以外的字符,相当于[^A-Za-z0-9_] |
\s | 匹配空格(包括换行符、制表符、空格等),相当于[\t\r\n\v\f] |
\S | 匹配非空格字符,相当于[^\t\r\n\v\f] |
例:日期 /^\d{4}-\d{1,2}-\d{1,2}$/
修饰符:
修饰符约束正则执行的某些细节行为,如是否区分大小写、是否支持多行匹配
语法:/表达式/修饰符
修饰符 | 说明 |
---|---|
i(ignore) | 不区分大小写 |
g(global) | 匹配所有满足正则表达式的结果 |
替换: replace 语法:字符串.replace(/正则表达式/,‘替换的文本’)
'学java,拿高薪,学JAVA就对了'.replace(/java/ig,'前端')