Web APIs学习 --DOM(一)
Web APIs
- 尽量用const,少用let,不用var。
- 数组和对象用const,数组和对象的元素和属性可以改变。因为const只是保证变量指向的内存地址不变,不保证内存地址的值不变。
基本认知
- Web API就是使用js去操作html和浏览器
- 分类:DOM(文档对象模型)、BOM(浏览器对象模型)
- DOM是用来呈现以及与任意HTML或XML文档交互的API,主要操作网页内容,比如对页面元素进行移动、大小、添加删除等操作。开发网页内容特效和实现用户交互
DOM树
将HTML文档以树状结构直观的表现出来,文档树直观的体现了标签与标签之间的关系。
- DOM树的节点类型
- 元素节点:HTML标签
- 文本节点:HTML文本
- 属性节点:HTML属性
- 注释节点:HTML注释
DOM对象
浏览器根据html标签生成的js对象,所有的标签属性都可以在这个对象上面找到,修改这个对象的属性会自动映射到标签身上。
1 | // 获取元素对象,在html中是标签,在js中获取到的是对象。 |
DOM的核心思想:把网页内容当作对象来处理,通过js操作DOM对象,从而改变页面内容
- document对象:代表整个文档,是DOM树的根节点,所以它所提供的属性和方法都是用来访问和操作网页内容的,网页所有内容都在document中。
获取DOM对象
- 根据CSS选择器获取元素对象
document.querySelector('css选择器')
:获取第一个符合条件的元素对象,返回值是一个HTMLElement对象document.querySelectorAll('css选择器')
:获取所有符合条件的元素对象,返回值是一个NodeList对象集合,获取到的是伪数组,有长度有索引,但是不能使用pop、push等数组方法。想要得到里面的每一个对象,可以使用forEach遍历。document.getElementById('id')
:根据id获取元素对象,返回值是一个HTMLElement对象document.getElementsByClassName('class')
:根据class获取元素对象,返回值是一个HTMLCollection对象集合document.getElementsByTagName('tag')
:根据标签名获取元素对象,返回值是一个HTMLCollection对象集合
CSS选择器
- 标签选择器:
div
,p
,span
- 类选择器:
.class
,.active
,.container
- id选择器:
#id
- 属性选择器:
div[class="container"]
- 伪类选择器:
:hover
,:active
,:first-child
- 伪元素选择器:
::before
,::after
- 后代选择器:
div p
指的是div下的所有p- 子元素选择器:
div > p
指的是div下的直接子元素p- 相邻兄弟选择器:
div + p
指的是div后面的第一个p- 通用选择器:
*
- 分组选择器:
div, p
指的是div和p
操作元素
操作元素内容
element.innerHTML
:获取元素内部的html内容,比如<div>hello</div>
,获取到的是hello
,将html内容添加到元素中,会解析html标签。element.innerText
:获取元素内部的文本内容,比如<div>hello</div>
,获取到的是hello
,将文本内容添加到元素中,会自动转义,不会解析html标签。
操作元素属性
element.style
:获取元素的样式,返回一个对象,可以通过这个对象修改元素的样式。如果是background-color这种属性,需要改成
小驼峰命名法,比如backgroundColor
。element.className
:获取元素的class属性,返回一个字符串,可以通过这个字符串修改元素的class属性。具体来说,事先在css中定义好样式,然后通过js修改元素的class属性,从而改变元素的样式。
如果原先有类名,要注意保留原来的类名。element.classList
:终极解决方案,为了解决className容易覆盖以前的类型,我们可以通过classList的方式追加和删除类名。1
2
3element.classList.add('active')
element.classList.remove('active')
element.classList.toggle('active') // 如果有就删除,没有就添加 切换
操作表单元素属性
element.value
:获取表单元素的值,比如input、textarea、select等。- 复选框、单选框、下拉框等表单元素,需要通过
element.checked
、element.selected
、element.disabled
等属性来操作。 - checked:复选框是否选中,selected:下拉框是否选中,disabled:表单元素是否禁用。
自定义属性
这是HTML5新增的属性,可以在标签上自定义属性,比如<div data-id="1"></div>
,可以通过element.dataset.id
获取到这个属性的值。意义是可以在标签上存储一些数据,方便js操作。
例子:1
2
3
4
5<div data-id="1"></div>
<script>
const div = document.querySelector('div')
console.log(div.dataset.id) // 1
</script>
定时器-间歇函数
情景:比如每隔一段时间就弹出一个警告框,或者每隔一段时间就改变一下页面的颜色等,倒计时。
- 开启定时器
setInterval(callback, time)
:每隔一段时间执行一次回调函数setTimeout(callback, time)
:延迟一段时间执行一次回调函数
- 关闭定时器
clearInterval(timer)
:关闭间歇函数clearTimeout(timer)
:关闭延时函数
- 例子:
1
2
3
4
5
6let timer = setInterval(() => {
console.log('hello')
}, 1000)
setTimeout(() => {
clearInterval(timer)
}, 5000)
事件监听
什么是事件? 事件是浏览器或用户自身执行的某种动作,比如点击、滚动、输入等。
- click:点击事件
- mouseover:鼠标移入事件
- mouseout:鼠标移出事件
- keydown:键盘按下事件
- keyup:键盘抬起事件
- scroll:滚动事件
- change:表单元素值改变事件
- focus:表单元素获取焦点事件
- blur:表单元素失去焦点事件
- input:表单元素输入事件
1 | // 事件监听 |
事件监听三要素:事件源、事件类型、事件处理函数
事件监听版本
- DOM L0级事件监听:
element.onclick = function() {}
- DOM L2级事件监听:
element.addEventListener('click', function() {})
- 区别:DOM L0级事件监听只能绑定一个事件,DOM L2级事件监听可以绑定多个事件。
利用js可以调用点击事件
1 | // 触发点击事件 |
焦点事件
- 例子:
1
2
3
4
5
6
7
8
9
10<input type="text" id="input">
<script>
const input = document.querySelector('#input')
input.addEventListener('focus', () => {
console.log('focus')
})
input.addEventListener('blur', () => {
console.log('blur')
})
</script>
键盘事件
- 例子:
1
2
3
4
5
6
7
8
9
10<input type="text" id="input">
<script>
const input = document.querySelector('#input')
input.addEventListener('keydown', () => {
console.log('keydown')
})
input.addEventListener('keyup', () => {
console.log('keyup')
})
</script>
用户输入文本事件
- 例子:
1
2
3
4
5
6
7<input type="text" id="input">
<script>
const input = document.querySelector('#input')
input.addEventListener('input', () => {
console.log('input')
})
</script>
事件对象
什么事事件对象?事件对象是浏览器自动传递给事件处理函数的一个对象,包含了事件的相关信息,比如事件源、事件类型、事件坐标等。比如点击事件,事件对象中包含了点击的坐标。
使用场景比如:可以判断用户按下的是哪个键,可以获取鼠标点击的坐标等,从而做出相应的操作。
1 | // 事件对象 |
常见的事件对象属性:
event.target
:事件源,触发事件的元素event.type
:事件类型,比如click、mouseover等event.clientX
:鼠标点击的x坐标(相对于窗口左上角)event.clientY
:鼠标点击的y坐标event.keyCode
:键盘按下的键的键码(不提倡)event.key
:键盘按下的键的键名(推荐),比如a
、b
、Enter
等event.offsetX
:鼠标点击的x坐标相对于事件源的x坐标(相对于DOM元素左上角)event.offsetY
:鼠标点击的y坐标相对于事件源的y坐标
环境对象
能够分析判断函数运行在不同环境中this的指向,比如在浏览器中,this指向window对象。代表当前运行环境。
回调函数
- 什么是回调函数?回调函数是作为参数传递给另一个函数的函数,当满足某种条件时,另一个函数会调用这个函数。
事件流
事件流与两个阶段说明
- 事件流指的是事件完整执行过程中的流动路径
- 两个阶段:捕获 / 冒泡
- 捕获阶段是从Document->ELement html->Element body->Element div,冒泡阶段是倒过来
- 实际工作都是使用事件冒泡为主
1 | DOM.addEventListener(事件类型,事件处理函数,是否使用捕获机制) |
事件捕获
从DOM根元素开始去执行对应的事件
事件冒泡
当一个元素的事件被触发时,同样的事件将会在该元素的所有祖先元素中依次被触发,这一过程被称为事件冒泡
事件冒泡是默认存在的。
阻止冒泡
因为默认有冒泡模式的存在,容易导致事件影响到父级元素,若想把事件限制在当前的元素内,就需要阻止事件冒泡。
组建事件冒泡需要拿到事件对象,
1 | 事件对象.stopPropagation() |
解绑事件
传统的on事件方法,如onclick可以直接使用null覆盖就可以实现。
removeEventListener(事件类型,事件处理函数,[获取捕获或者冒泡阶段])
匿名函数无法解绑
鼠标经过事件的区别
- mouseover和mouseout 会有冒泡效果的
- mouseenter和mouseleave 没有冒泡效果 推荐
事件委托
以前要用for循环来给多个元素注册事件,利用事件冒泡减少注册次数,提高程序性能。
给父元素注册事件,当我们触发子元素的时候,会冒泡到父元素身上,从而触发父元素的事件。
通过事件对象中的target可以找到子元素,target.tagName(大写)可以获得真正触发事件的元素
阻止默认行为
比如,阻止链接的跳转,表单域跳转
1 | 事件对象.preventDefault() |
其他事件
页面加载事件
加载外部资源,比如图片、音频、视频等完毕后触发的事件
1
2
3
4window.addEventListener('load', () => {
console.log('load')
})
// 也可以任意一个dom元素增加load事件,意思是这个元素加载完毕后触发当初始的HTML文档被完全加载和解析完成之后,DOMContentLoaded事件被触发,无需等待样式表、图像和子框架的加载完成。
1
2
3document.addEventListener('DOMContentLoaded', () => {
console.log('DOMContentLoaded')
})
元素滚动事件
滚动条在滚动的时候持续触发的事件,应该将事件添加给window对象,因为滚动条是window对象的属性。
1 | window.addEventListener('scroll', () => { |
- scrollTop:元素滚动条距离顶部的距离
- scrollLeft:元素滚动条距离左边的距禿
- scrollHeight:元素内容的总高度
- scrollWidth:元素内容的总宽度
document.documentElement是html元素,document.body是body元素
scrollTo(x,y):滚动到指定坐标
scroll_behavior: smooth; 平滑滚动
页面尺寸事件
窗口尺寸改变触发事件resize
clientWidth和clientHeight:元素可视区域的宽度,不包括滚动条、margin、border,包括padding
offsetWidth和offsetHeight:获取元素自身的设置的宽高、padding、border。可视宽高,如果隐藏,获取的是0 只读
offsetLeft和offsetTop: 只读 获取元素距离自己定位父级的距离
元素尺寸位置 element.getBoundingClientRect() 返回一个对象,元素的大小及其相对于视口的位置