Web APIs

  • 尽量用const,少用let,不用var。
  • 数组和对象用const,数组和对象的元素和属性可以改变。因为const只是保证变量指向的内存地址不变,不保证内存地址的值不变。

基本认知

  • Web API就是使用js去操作html和浏览器
  • 分类:DOM(文档对象模型)、BOM(浏览器对象模型)
  • DOM是用来呈现以及与任意HTML或XML文档交互的API,主要操作网页内容,比如对页面元素进行移动、大小、添加删除等操作。开发网页内容特效和实现用户交互

DOM树

将HTML文档以树状结构直观的表现出来,文档树直观的体现了标签与标签之间的关系。
DOM树

  • DOM树的节点类型
    • 元素节点:HTML标签
    • 文本节点:HTML文本
    • 属性节点:HTML属性
    • 注释节点:HTML注释

DOM对象

浏览器根据html标签生成的js对象,所有的标签属性都可以在这个对象上面找到,修改这个对象的属性会自动映射到标签身上。

1
2
// 获取元素对象,在html中是标签,在js中获取到的是对象。
const div = document.querySelector('div')

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选择器

  • 标签选择器:divpspan
  • 类选择器:.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
      3
      element.classList.add('active')
      element.classList.remove('active')
      element.classList.toggle('active') // 如果有就删除,没有就添加 切换
  • 操作表单元素属性

    • element.value:获取表单元素的值,比如input、textarea、select等。
    • 复选框、单选框、下拉框等表单元素,需要通过element.checkedelement.selectedelement.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
    6
    let timer = setInterval(() => {
    console.log('hello')
    }, 1000)
    setTimeout(() => {
    clearInterval(timer)
    }, 5000)

事件监听

什么是事件? 事件是浏览器或用户自身执行的某种动作,比如点击、滚动、输入等。

  • click:点击事件
  • mouseover:鼠标移入事件
  • mouseout:鼠标移出事件
  • keydown:键盘按下事件
  • keyup:键盘抬起事件
  • scroll:滚动事件
  • change:表单元素值改变事件
  • focus:表单元素获取焦点事件
  • blur:表单元素失去焦点事件
  • input:表单元素输入事件
1
2
3
4
// 事件监听
element.addEventListener('click', () => {
console.log('click')
})

事件监听三要素:事件源、事件类型、事件处理函数

事件监听版本

  • DOM L0级事件监听:element.onclick = function() {}
  • DOM L2级事件监听:element.addEventListener('click', function() {})
  • 区别:DOM L0级事件监听只能绑定一个事件,DOM L2级事件监听可以绑定多个事件。

利用js可以调用点击事件

1
2
// 触发点击事件
element.click()

焦点事件

  • 例子:
    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
2
3
4
// 事件对象
element.addEventListener('click', (event) => {
console.log(event)
})

常见的事件对象属性:

  • event.target:事件源,触发事件的元素
  • event.type:事件类型,比如click、mouseover等
  • event.clientX:鼠标点击的x坐标(相对于窗口左上角
  • event.clientY:鼠标点击的y坐标
  • event.keyCode:键盘按下的键的键码(不提倡)
  • event.key:键盘按下的键的键名(推荐),比如abEnter
  • event.offsetX:鼠标点击的x坐标相对于事件源的x坐标(相对于DOM元素左上角
  • event.offsetY:鼠标点击的y坐标相对于事件源的y坐标

环境对象

能够分析判断函数运行在不同环境中this的指向,比如在浏览器中,this指向window对象。代表当前运行环境。

回调函数

  • 什么是回调函数?回调函数是作为参数传递给另一个函数的函数,当满足某种条件时,另一个函数会调用这个函数。

事件流

事件流与两个阶段说明

  • 事件流指的是事件完整执行过程中的流动路径
  • 两个阶段:捕获 / 冒泡
  • 捕获阶段是从Document->ELement html->Element body->Element div,冒泡阶段是倒过来
  • 实际工作都是使用事件冒泡为主
1
2
DOM.addEventListener(事件类型,事件处理函数,是否使用捕获机制)
// true是捕获,false是冒泡,默认是false

事件捕获

从DOM根元素开始去执行对应的事件

事件冒泡

当一个元素的事件被触发时,同样的事件将会在该元素的所有祖先元素中依次被触发,这一过程被称为事件冒泡

事件冒泡是默认存在的。

阻止冒泡

因为默认有冒泡模式的存在,容易导致事件影响到父级元素,若想把事件限制在当前的元素内,就需要阻止事件冒泡。

组建事件冒泡需要拿到事件对象,

1
2
事件对象.stopPropagation()
// 阻断事件流动传播,包括冒泡阶段和捕获阶段

解绑事件

传统的on事件方法,如onclick可以直接使用null覆盖就可以实现。

removeEventListener(事件类型,事件处理函数,[获取捕获或者冒泡阶段])

匿名函数无法解绑

鼠标经过事件的区别

  1. mouseover和mouseout 会有冒泡效果的
  2. mouseenter和mouseleave 没有冒泡效果 推荐

事件委托

以前要用for循环来给多个元素注册事件,利用事件冒泡减少注册次数,提高程序性能。

给父元素注册事件,当我们触发子元素的时候,会冒泡到父元素身上,从而触发父元素的事件。

通过事件对象中的target可以找到子元素,target.tagName(大写)可以获得真正触发事件的元素

阻止默认行为

比如,阻止链接的跳转,表单域跳转

1
事件对象.preventDefault()

其他事件

页面加载事件

  1. 加载外部资源,比如图片、音频、视频等完毕后触发的事件

    1
    2
    3
    4
    window.addEventListener('load', () => {
    console.log('load')
    })
    // 也可以任意一个dom元素增加load事件,意思是这个元素加载完毕后触发
  2. 当初始的HTML文档被完全加载和解析完成之后,DOMContentLoaded事件被触发,无需等待样式表、图像和子框架的加载完成。

    1
    2
    3
    document.addEventListener('DOMContentLoaded', () => {
    console.log('DOMContentLoaded')
    })

元素滚动事件

滚动条在滚动的时候持续触发的事件,应该将事件添加给window对象,因为滚动条是window对象的属性。

1
2
3
4
window.addEventListener('scroll', () => {
console.log('scroll')
document.documentElement.scrollTop // 滚动条距离顶部的距离
})
  • 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() 返回一个对象,元素的大小及其相对于视口的位置