文章目录
Web API
作用:就是使用JavaScript去操作html和浏览器
分类:DOM(文档对象模型),BOM(浏览器对象模型)
DOM
DOM(Document Object Model):是用来呈现以及与任意HTML或XML文档交互的API
DOM的作用:开发网页内容特效和实现用户交互
DOM树:
将HTML文档以树状的结构直观的表现出来,我们称之为文档树或DOM树
文档树直观的体现了标签与标签之间的关系
DOM对象:浏览器根据HTML标签自动生成的JavaScript对象
- 所有的标签属性都可以在这个对象上面找到
- 修改这个对象的属性会自动映射到标签身上
DOM的核心思想
- 把网页内容当做对象来处理
document对象:
- 是DOM里面提供的一个对象
- 所以它提供的属性和方法都是用来访问和操作网页内容的
- 网页所有内容都在document里面
获取DOM对象
选择匹配的第一个元素:
// 获取第一个匹配的标签
let div = document.querySelector("css选择器")
- 参数说明:包含一个或多个有效的css选择器字符串
- 返回值:CSS选择器匹配的第一个元素,一个HTMLElement对象,如果没有匹配到则返回null
选择匹配的多个元素:
// 获取所有匹配的元素
let divs = document.querySelectorAll('css选择器')
-
参数说明:包含一个或多个有效的css选择器字符串
-
返回值:CSS选择器匹配的NodeList 对象集合,是一个伪数组
- 伪数组:有长度有索引号,但是没有pop,push等数组方法
-
想要得到里面的对象,需要遍历
// 获取所有div
let div = document.querySelectorAll('div')
// 打印div
console.log(div)
// 遍历
for(let i = 0;i < div.length;i++) {
// 打印每一个元素
console.log(div[i])
}
其他获取DOM对象的方法了解即可(用到时百度即可)
修改DOM内容
document.write():里面的标签会被解析
元素的innerText属性:文本中包含的标签不会解析
// 获取div
let divs = document.querySelector('div')
divs.innerText = '我一定不好了'
元素的innerHTML属性:标签会被解析
修改DOM属性
通过JavaScript设置修改标签元素的属性
语法:
对象.属性 = 值
// 得到img标签
let img = document.querySelector('img')
img.src = 'img/1.png'
修改DOM样式属性
通过JavaScript设置修改标签的样式属性
通过style属性操作CSS
语法:
对象.style.样式属性 = 值
- 样式属性采用小驼峰命名法
let box = document.querySelector('div')
box.style.backgroundColor = 'red'
通过className属性操作CSS
语法:
元素.className = '类名'
let box = document.querySelector('div')
box.className = 'active'
- 但是如果<div>本来就有one一个类,这样做会覆盖掉以前的类
let box = document.querySelector('div')
// 防止覆盖
box.className = 'one active'
通过classList操作类控制CSS
语法
// 追加一个类
元素.classList.add('类名')
// 删除一个类
元素.classList.remove('类名')
// 切换一个类
元素.classList.toggle('类名') // 有这个类就减去,没有这个类就加上
修改表单元素属性
语法
表单.属性 = 值
let input = document.querySelector('input')
input.value = '' // 清空
- 如果有disabled,checked,selected这三个属属性,采取布尔值
定时器
setInterval(函数, 间隙时间)
- 每个一段时间自动调用这个函数(匿名函数)
- 单位是毫秒
setInterval(function() {
console.log('开心每一天')
}, 1000)
function show() {
console.log('开心每一天')
}
setInterval(show, 1000) // show绝对不要加小括号
停止定时器
let 变量名 = setInterval(函数, 间隙时间)
clearInterval(变量名)
function show() {
console.log('开心每一天')
}
let timer = setInterval(show, 1000)
clearInterval(timer)
案例
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style>
div {
overflow: auto;
width: 200px;
height: 100px;
border: 1px solid black;
}
</style>
</head>
<body>
<div>
用户协议用户协议用户协议
用户协议用户协议用户协议
用户协议用户协议用户协议
用户协议用户协议用户协议
用户协议用户协议用户协议
用户协议用户协议用户协议
用户协议用户协议用户协议
用户协议用户协议用户协议
用户协议用户协议用户协议
用户协议用户协议用户协议
用户协议
</div>
<button disabled>同意协议</button>
<script>
let btn = document.querySelector('button')
let num = 6
let re = setInterval(function(){
num --
btn.innerHTML = `同意协议${num}`
if(num === 0) {
clearInterval(re)
btn.disabled = false
btn.innerHTML = '同意协议'
}
}, 1000)
</script>
</body>
</html>
事件
事件是在编程时系统内发生的动作或者发生的事情,比如用户在网页上单击了一个按钮
事件监听:就是让程序检测是否有事件产生,一旦有事件触发,就立即调用一个函数做出响应,也称为注册事件
语法
元素.addEventListener('事件', 要执行的函数)
事件监听三要素:
- 事件源:被事件监听的DOM元素
- 事件:用什么方式触发
- 事件调用的函数:事件的执行函数
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div>点击我</div>
<script>
let box = document.querySelector('div')
box.addEventListener('click', function() {
alert('我被点击了')
})
</script>
</body>
</html>
环境对象指的是函数内部特殊的变量this,它代表着当前函数运行时所处的环境
this:谁调用它它就指向谁,this是一个对象,箭头函数在JavaScript高级部分在介绍
排他思想(了解即可)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style>
.pink {
background-color: blue;
}
</style>
</head>
<body>
<button>第1个</button>
<button>第2个</button>
<button>第3个</button>
<button>第4个</button>
<button>第5个</button>
<script>
let btns = document.querySelectorAll('button')
for(let i = 0;i < btns.length;i++) {
btns[i].addEventListener('click', function() {
// 干掉所有人
for(let j = 0;j < btns.length;j++) {
btns[j].classList.remove('pink')
}
// 复活我自己
this.classList.add('pink')
})
}
</script>
</body>
</html>
DOM节点
DOM树里面的每一个内容都称之为节点
节点类型
元素节点:所有的标签对象
属性节点:所有的属性
文本节点:所有文本
查找节点
查找父节点
- parentNode属性
- 返回最近一级的父节点,找不到返回空
元素.parentNode
查找子节点
- childNodes
- 获取所有子节点,包括文本节点(空格,换行),注释节点等
- children属性
- 仅获得所有元素子节点,返回的是一个伪数组
父元素.children
查找兄弟节点
下一个兄弟节点
- nextElementSibling属性
上一个兄弟节点
- previousElementSibling属性
增加节点
创建节点
创建一个新的网页元素,在添加到网页内,一般先创建节点,然后插入节点
- 创建节点
document.createElement('标签名')
// 创建一个新的节点
let p = document.createElement('p')
追加节点
插入到父元素的最后一个子元素
父元素.appendChild(要插入的元素)
// 查询到第一个ul标签
let ul = document.querySelector('ul')
// 创建一个新的小li节点
let li = document.createElement('li')
// 向ul标签中插入li标签
ul.appendChild(li)
插入到父元素中某个子元素的前面
父元素.insertBefore(要插入的元素, 在哪个元素前面)
// 查询到第一个ul标签
let ul = document.querySelector('ul')
// 创建一个新的小li节点
let li = document.createElement('li')
// 在ul的第二个元素前面插入一个小li
ul.insertBefore(li, ul.children[1])
克隆节点
元素.cloneNode(布尔值)
- 值为true时,则代表克隆时会包含后代节点一起克隆
- 值为false时,则代表克隆时不会包含后代节点
- 默认为false
删除节点
父元素.removeChild(要删除的元素)
// 查询到第一个ul标签
let ul = document.querySelector('ul')
ul.removeChild(ul.children[0])
时间对象
得到当前系统时间
- 创建一个时间对象并获取当前时间
let date = new Date()
获得指定时间
let date = new Date('1949-10-01')
方法
时间戳
时间戳是指1970年01月01日00时00分00秒起到现在的毫秒数,它是一种特殊的计量时间的方式
三种方法获取时间戳
getTime()方法
let date = new Date()
// 获取时间戳
date.getTime()
简写+new Date()
// 获取时间戳
console.log(+new Date())
使用Date.now()
console.log(Date.now())
- 解析(Parser)HTML:生成DOM树
- 同时解析(Parser)CSS:生成样式规则
- 根据DOM树和样式规则,生成渲染树
- 进行布局Layout(回流/重排):根据生成的渲染树,得到节点的几何信息
- 进行绘制Painting(重绘):根据计算和获取的信息进行整个页面的绘制
- Display:展示在页面上
回流:当Render Tree中部分或者全部元素的尺寸,结构,布局发生改变时,浏览器就会重新渲染部分或者全部文档的过程称为回流
由于节点的样式改变并不影响它在文档流中的位置和文档布局时,称为重绘
重绘不一定引起回流,而回流一定会引起重绘
事件对象
事件对象
获取事件对象
也是一个对象,这个对象中有事件触发时的相关信息
例如:鼠标点击事件中,事件对象就存储了鼠标点在哪个位置等信息
获取事件对象
在事件绑定的回调函数的第一个参数就是事件对象
元素.addEventListener('click', function(e) {
})
- 部分常用属性
事件流
事件流:指的是事件完整执行过程中的流动路径
事件冒泡:当一个元素的事件被触发时,同样的事件将会在该元素的所有祖先元素中依次被触发,这一过程被称为事件冒泡
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style>
.father {
margin: 100px auto;
width: 500px;
height: 500px;
background-color: blue;
}
.son {
width: 200px;
height: 200px;
background-color: red;
}
</style>
</head>
<body>
<div class="father">
<div class="son"></div>
</div>
<script>
let fa = document.querySelector('.father')
let son = document.querySelector('.son')
fa.addEventListener('click', function() {
alert('我是爸爸')
})
son.addEventListener('click', function() {
// 同时触发父元素的同名事件
alert('我是儿子')
})
</script>
</body>
</html>
事件捕获:从DOM的根元素开始去执行对应的事件
元素.addEventListener('事件', 要执行的函数, 是否使用捕获机制)
- 第三个参数传入true时代表是捕获阶段触发
- 传入false时代表冒泡阶段触发,默认false
阻止事件流动
阻止事件流动必须要有事件对象
事件对象.stopPropagation()
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style>
.father {
margin: 100px auto;
width: 500px;
height: 500px;
background-color: blue;
}
.son {
width: 200px;
height: 200px;
background-color: red;
}
</style>
</head>
<body>
<div class="father">
<div class="son"></div>
</div>
<script>
let fa = document.querySelector('.father')
let son = document.querySelector('.son')
fa.addEventListener('click', function() {
alert('我是爸爸')
})
son.addEventListener('click', function(e) {
// 阻止事件冒泡
e.stopPropagation()
alert('我是儿子')
})
</script>
</body>
</html>
- mouseover和mouseout会有冒泡效果
- mouseenter和mouseleave没有冒泡效果(推荐)
阻止默认行为,链接的跳转和表单的提交
e.preventDefault()
事件委托
事件委托是利用事件流的特征解决一些问题
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<ul>
<li>我是第1个</li>
<li>我是第2个</li>
<li>我是第3个</li>
<li>我是第4个</li>
<li>我是第5个</li>
</ul>
<script>
// 不要每个li都添加事件了,而是委托给他的父级,利用事件冒泡
let ul = document.querySelector('ul')
ul.addEventListener('click', function(e) {
alert('我被点击了')
// 得到当前的元素
// console.log(e)
// console.log(e.target)
e.target.style.color = 'red'
})
</script>
</body>
</html>
滚动事件和加载事件
滚动事件
当页面滚动时触发的事件
事件名:scroll
监听整个页面滚动
window.addEventListener('scroll', function() {
})
加载事件
有时候需要等页面资源全部处理完了做一些事情
事件名:load
监听页面所有资源加载完毕
window.addEventListener('load', function() {
})
// 只需要加载dom树即可
window.addEventListener('DOMContentLoaded', function() {
})
元素大小和位置获取
scroll家族
我们想让页面滚动一段距离,就让某些元素做一些事情,使用scroll来检测页面滚动的距离
- 获取宽高
获取元素的内容总宽高(不包括滚动条),返回值不带单位
scrollWidth和scrollHeight属性
- 获取位置
获取元素内容往左,往右滚出去看不到的距离
scrollLeft和scrollTop
这两个属性可以修改
- 检测页面滚动距离
在开发中,我们经常检测页面滚动的距离,比如页面滚动100像素,就可以显示一个元素,或者固定一个元素
window.addEventListener('scroll', function() {
let num = document.documentElement.scrollTop
console.log(num)
})
offset家族
- 获取宽高
获取元素自身的宽高,包含元素自身设置的宽高(padding border)
offsetWidth和offsetHeight属性
- 获取位置
获取元素距离自己定位父级元素的左,上距离
offsetLeft和offsetTop属性,注意是只读属性
client家族
- 获取宽高
获取元素的可见部分宽高(不包含边框,滚动条)
clientWidth和clientHeight属性
- 获取位置
获取左边框和上边框宽度
clientLeft和clientTop属性,注意是只读属性
resize
会在窗口尺寸改变的时候触发事件
window.addEventListener('resize', function() {
})
window.addEventListener('resize', function() {
// 获取整个屏幕宽度
document.documentElement.clientWidth
})
BOM
BOM(Browser Object Model):浏览器对象模型
- Window是浏览器内置中的全局对象
延迟函数
JavaScript内置的一个用来让代码延迟执行的函数,叫setTimeout
语法:
setTimeout(回调函数, 等待的毫秒数)
- setTimeout仅仅只执行一次,所以可以理解为就是把一段代码延迟执行
let timer = setTimeout(回调函数, 等待的毫秒数)
clearTimeout(timer)
location对象
常用属性和方法
- href属性:获取完整URL地址,对其赋值时用于地址的跳转
- search属性:获取地址中携带的参数
- hash属性:获取地址中的hash值,#后面的部分
- reload方法:用来刷新当前页面,传入参数true时表示强制刷新
history对象
常用属性和方法
JavaScript执行机制
JavaScript的一大特点是单线程,也就是说,同一时间只能做一件事,这是因为JavaScript这门脚本语言诞生的使命所致,它是为了处理页面中用户的交互,以及操作DOM而诞生的,比如我们对某个DOM进行添加和删除操作,不能同时进行,应该先添加,再删除
单线程就意味着所有任务都需要排队,前一个任务结束,才会执行下一个任务,这样所导致的问题是:如果JavaScript执行的时间过长,这样就会造成页面渲染不连贯,导致页面渲染加载阻塞
为了解决这个问题,利用多核CPU的计算能力,HTML5提出Web Worker标准,允许JavaScript脚本创建多个线程,于是,JavaScript中出现了同步和异步
同步:前一个任务结束后再执行后一个任务
异步:多个任务同时进行,互不影响
同步任务都在主线程上执行,形成一个执行栈
JavaScript的异步任务是通过回调函数实现的,异步任务会添加到任务队列中,
- 先执行执行栈里面的同步任务,依次执行
- 发现有回调函数,将这个回调函数放入任务队列中
- 一旦执行栈里面的同步任务执行完毕,系统就会安照次序读取任务队列中的异步任务,于是结束等待状态,放入执行栈中,开始执行
正则表达式
是用于匹配字符串中字符组合的模式,在JavaScript中,正则表达式也是对象
定义正则表达式
JavaScript中定义正则表达式的语法有两种,这里只介绍其中一种
let 变量名 = /表达式/
判断是否有符合要求的字符串
test()方法:用来查看正则表达式与指定的字符串是否匹配
检索符合规则的字符串
exec()方法:在一个指定字符串中执行一个搜索匹配
元字符
边界符
正则表达式中的边界符用来提示字符所处的位置,主要有两个字符
量词
量词用来设定某个模式出现的次数
字符类
-
[]:匹配字符集合
-
连字符:[]里面加上-,使用连字符表示一个范围
例如:[a-z]:表示a到z都可以
- 预定义:某些常见模式的简写方式