Skip to content

WebAPI

和标准库不同,WebAPI 是浏览器提供的一套 API,用于操作浏览器窗口和界面

WebAPI 中包含两个部分:

  • BOM:Browser Object Model,浏览器模型,提供和浏览器相关的操作
  • DOM:Document Object Model,文档模型,提供和页面相关的操作
image-20211215154639275

BOM

BOM 提供了一系列的对象和函数,提供和浏览器本身相关的操作

window

全局对象

https://developer.mozilla.org/zh-CN/docs/Web/API/Window/window

API含义备注
open()打开一个新的浏览器窗口返回新窗口的 window 对象
close()关闭浏览器窗口只能关闭使用 open 打开的浏览器窗口
==setTimeout()==设置一个计时器
在一段时间后自动执行某个函数
参数 1:函数,无参,this 指向 window
参数 2:时间,毫秒
返回:计时器的 ID
==clearTimeout()==清除指定 ID 的计时器传入计时器的 ID
==setInterval()==设置一个计时器
每隔一段时间自动执行某个函数
参数 1:函数,无参,this 指向 window
参数 2:时间,毫秒
返回:计时器的 ID
==clearInterval()==清除指定 ID 的计时器传入计时器的 ID
alert()弹出提示框不同的操作系统外观有差异
confirm()弹出确认框不同的操作系统外观有差异
js
let timerId=nul;
function start(){
  if(timerId){
    return;
  }
  timerId=setInterval(()=>{
    console.log(new Date());
  })
}

function stop(){
 clearInterval(timerId);
 timerId=null;
}

window.location

https://developer.mozilla.org/zh-CN/docs/Web/API/Location

提供地址栏的相关操作

API含义备注
==Location.href==获取或设置页面当前地址设置地址回导致页面跳转
Location.protocol获取或设置地址中的协议部分
Location.host获取或设置地址中的主机名和端口号
Location.hostname获取或设置地址中的主机名
Location.port获取或设置地址中的端口号
Location.pathname获取或设置地址中的路径部分
Location.search获取或设置地址中的参数部分
Location.hash获取或设置地址中的 hash 部分
Location.reload()刷新页面

window.history

https://developer.mozilla.org/zh-CN/docs/Web/API/History

提供当前窗口历史记录的操作

API含义备注
History.back()后退
History.forward()前进
History.go()根据相对当前页面的偏移量,
进入指定的记录页
History.pushState()在历史记录中添加一条记录页面不刷新
History.replaceState()替换当前记录页面不刷新

DOM

DOM 是一个对象,它对应到 HTML 中的节点

image-20211215164209559

获取 dom

API含义备注
document.getElementById()根据元素 id 获取 dom得到单个 dom
document.getElementsByTagName()
dom.getElementsByTagName()
根据元素名称获取 dom得到 dom 的伪数组
document.getElementsByClassName()
dom.getElementsByClassName()
根据元素类样式获取 dom得到 dom 的伪数组
==document.querySelector()==
==dom.querySelector()==
根据 CSS 选择器获取 dom得到第一个匹配的 dom
==document.querySelectorAll()==
==dom.querySelectorAll()==
根据 CSS 选择器获取 dom得到所有匹配的 dom
伪数组
==document.documentElement==获取 html 元素
document.body获取 body
document.head获取 head
==dom.children==获取 dom 的子元素得到 dom 的伪数组
dom.childNodes获取 dom 的子节点得到 dom 节点的伪数组
关于节点对象点这里
dom.previousElementSibling得到 dom 前一个兄弟元素
dom.nextElementSibling得到 dom 后一个兄弟元素
==dom.parentElement==得到 dom 的父元素

创建 dom

API含义备注
==document.createElement()==创建一个 dom 并返回传入元素名称

更改 dom 结构

这里是指更改文档树(DOM 树)

API含义备注
==dom.remove()==从文档树中删除 dom不是删除对象
dom.removeChild()删除 dom 的某个子节点传入 dom 对象
dom.insertBefore()在 dom 的子节点中,添加一个新节点到另一个节点之前
==dom.appendChild()==添加一个新节点到 dom 的子节点末尾传入 dom 对象

dom 属性

本节的「属性」,是指 HTML 元素的「属性」

属性有两种:

  • 标准属性:HTML 元素本身拥有的属性,例如:
    • a 元素的 href、title
    • input 的 value
    • img 的 src
    • ......
  • 自定义属性:HTML 元素标准中未定义的属性

所有标准属性均可通过 dom.属性名 得到,其中:

  • 布尔属性会被自动转换为 boolean

  • 路径类的属性会被转换为绝对路径

  • 标准属性始终都是存在的,不管你是否有在元素中属性该属性

  • class 由于和关键字重名,因此需要使用 className

所有的自定义属性均可通过下面的方式操作:

  • dom.setAttribute(name, value),设置属性键值对
  • dom.getAttribute(name),获取属性值

自定义属性和元素源码书写是对应的,可以尝试获取 a 元素的 href 属性对比标准属性,看看有什么不同。

dom 内容

API含义备注
==dom.innerText==获取或设置元素文本内容设置时会自动进行 HTML 实体编码
==dom.innerHTML==获取或设置元素的 HTML 内容

dom 样式

在 JS 中,有两种样式:

  • 内联样式:元素的 style 属性中书写的样式
  • 计算样式(最终样式):元素最终计算出来的样式

JS 可以获取内联样式和计算样式,但只能设置内联样式

下面罗列了样式的常见操作:

  • dom.style:获取元素的内联样式,得到样式对象
    • 对象中的所有样式属性均可以被赋值,赋值后即可应用样式到元素的 style 中
  • getComputedStyle(dom):获取元素的计算样式,得到一个样式对象
    • 该样式对象中的属性是只读的,无法被重新赋值

关于样式对象,注意:

  • 当给样式赋值为空字符串时,相当于删除内联样式
  • 当给样式的赋值不合法时,赋值语句无效,不会报错
  • CSS 的短横线命名法,在属性名中表现为驼峰命名法

监听 dom 事件

监听事件可以描述为一句话:

某个 DOM发生了某件事之后,我需要做某些处理

  • 某个 DOM:监听谁?
  • 某件事(事件类型):它发生了什么?
  • 某些处理(处理函数):我要做什么?

下面是一段事件监听代码:

js
// 为dom注册点击事件,当被点击时,自动运行事件处理函数
dom.onclick = function () {
  console.log("dom 被点击了");
};

事件类型

https://developer.mozilla.org/zh-CN/docs/Web/Events

表单类事件
事件名称触发时机备注
==submit==表单被提交时触发注册到 form 元素上
==input==文本框改变后立即出发注册到 input、textarea 上
==change==文本框改变后、失去焦点时触发
下拉列表、多选框、单选框改变后立即触发
注册到 input、select、textarea 上
reset表单被重置时触发注册到 form 元素上
focus元素聚焦时触发
blur元素失去焦点时触发
鼠标类事件
事件名称触发时机备注
==click==鼠标按下抬起后触发
contextmenu右键菜单显示前触发
==mousedown==鼠标按下时触发
==mouseup==鼠标抬起时触发
==mousemove==鼠标在元素上移动时触发
==mouseenter==鼠标进入元素时触发(不冒泡)
==mouseleave==鼠标离开元素时触发(不冒泡)
mouseover鼠标进入元素时触发(冒泡)
mouseout鼠标离开元素时触发(冒泡)
wheel鼠标滚轮滚动时触发
键盘事件
事件名称触发时机备注
keydown某个键被按下时触发
keyup某个键被抬起时触发

注册事件

JS 提供了三种方式注册事件

方式 1:将事件注册写到元素上,这种方式基本被弃用

html
<button onclick="js代码">按钮</button>

==方式 2:使用 dom 属性注册事件==

属性名为on+事件类型

js
// 监听事件
dom.onclick = function () {
  // 处理函数
};
// 移除监听事件
dom.onclick = null;

这种方式的特点是:

  • 优点:易于监听、覆盖、移除
  • 缺点:只能注册一个处理函数
  • 缺点:某些事件不支持用这种方式注册

==方式 3:使用 addEventListener 方法注册事件==

js
dom.addEventListener("click", function () {
  // 处理函数1
});
dom.addEventListener("click", function () {
  // 处理函数2
});

这是最完美的事件注册方式,如果要移除用这种方式注册的事件,需要改写代码

js
function handler1() {
  // 处理函数1
}
function handler2() {
  // 处理函数2
}

dom.addEventListener("click", handler1);
dom.addEventListener("click", handler2);

dom.removeEventListener("click", handler1); // 移除监听函数1

事件处理函数

当事件发生时,会自动调用事件处理函数,并向函数传递一个参数,该参数称之为事件对象,里面包含了事件发生的相关信息,比如鼠标位置、键盘按键等等

js
dom.addEventListener("click", function (e) {
  console.log(e.clientX); //打印鼠标的横坐标
});

常见的事件对象有:鼠标事件对象键盘事件对象

另外,在事件处理函数中,this始终指向注册事件的 dom

dom 进阶

事件默认行为

某些元素的某些事件,浏览器会有自己的默认行为

比如:

  • a 元素的 click 事件,浏览器会跳转页面
  • form 元素的 submit 事件,浏览器会提交表单,最终导致页面刷新
  • 文本框的 keydown 事件,浏览器会将按键文本显示到文本框中
  • ......

如果我们要阻止浏览器的默认行为,就需要在对应时间中加入以下代码:

js
// e为事件对象
e.preventDefault();

dom 尺寸和位置

尺寸1

尺寸2

尺寸3

尺寸4

调用dom.scrollTo(x, y)可以设置元素的滚动位置,x 和 y 分别表示 scrollLeft 和 scrollTop

该方法通用元素回到元素顶部dom.scrollTo(0, 0)

如果要监听元素的滚动,可以监听事件类型:==scroll==

Element.getBoundingClientRect()

element-box-diagram

上图中的 top、left、right、bottom 均相对于视口

事件传播机制

事件流
js
// 在冒泡阶段触发
div.onclick = function () {};

// 在捕获阶段触发事件
div.addEventListener("click", function () {}, true);

// 在冒泡阶段触发事件(默认)
div.addEventListener("click", function () {}, false);
js
// 事件处理函数
function handler(e) {
  e.target; // 获取事件源(目标阶段的dom)
  e.stopPropagation(); // 阻止事件继续冒泡
}

汇总

  1. window 的尺寸
innnerWidth innerHeight浏览器视口尺寸(含滚动条)
clientWidth clientHeight视口内容区尺寸(不含滚动条)document.documentElement
scrollX scrollY文档滚动偏移
outerWidth outerHeight浏览器外部尺寸(含滚动条)
  1. 元素的尺寸位置 尺寸
offsetWidth offsetHeight盒子实际尺寸占位( 包含内容 + 内边距 + 边框 + 滚动条)
clientWidth clientHeight盒子在可见内容区的尺寸 (包含内容 + 内边距,不含边框和滚动条宽度)
scrollWidth scrollHeight元素内容的总尺寸(包括溢出被隐藏的部分,不含边框)
scrollTop scrollLeft元素内部滚动与内容尺寸(内部内容滚动的距离)

位置

offsetTop offsetLeft相对于 offsetParent 的偏移量(受定位上下文影响)
getBoundingClientRect()获取元素的矩阵信息 视口坐标系(相对于视口) 包含内边距与边框,不含外边距
  1. 事件参数
clientX clientYMouseEvent 鼠标位置(相对视口的坐标)
pageX pageYMouseEvent 相对于文档的坐标 (包含滚动偏移)
.screenX screenYMouseEvent 相对于整个屏幕的坐标
  1. js 常用 API

scrollIntoView

将元素滚动到可是区域,不可设置具体的像素值

javascript
dom.scrollIntoView({
  block: "top",
  behavior: "smooth",
});

scrollTo/scrollBy

文档滚动控制,可指定具体坐标

js
window.scrollTo({
  top: 50,
  behavior: "smooth",
});

ResizeObserver()

观测元素内容盒尺寸变化,替代轮询

js
const ro = new ResizeObserver((entries) => {
  for (const e of entries)
    console.log(e.contentRect.width, e.contentRect.height);
});

ro.observe(document.querySelector(".box"));

IntersectionObserver

是否与视口相交,常用于判断元素是否进入视口,懒加载常用

javascript
const io = new IntersectionObserver(
  ([e]) => {
    if (e.isIntersecting) {
      console.log("相交了");
    }
  },
  { threshold: 0.5 }
); //阈值:50%可见才触发

io.observe(document.querySelector(".box"));

MIT License