加载中,请稍等...

MDN Translations

API 开始时间 结束时间 最近复核时间
Local Font Access API 2023/11/30 2023/12/10 2024/03/31
Barcode Detection API 2023/12/13 2023/12/20 2024/03/31
Web Locks API 2023/12/19 2024/01/09 2024/03/31
Badging API 2024/01/10 2024/01/31 2024/03/31
Notifications API 2024/01/31 2024/02/14 2024/03/31
Battery Status API 2024/02/08 2024/03/31 2024/03/31
Network Information API 2024/03/30 2024/04/04 2024/04/04
User-Agent Client Hints API 2024/04/03 2024/04/15 2024/04/15
Vibrate API 2024/04/17 - -
Web Share API 2024/04/18 - -
Permissions API 2024/04/20 - -
  

WebOTP API

WebOTP API 是对 Credential Management API 的扩展,允许开发者请求用户访问短信验证码,以便方便地完成表单等填写

使用

使用 CredentialsContainer.get() 方法并指定 otp 选项请求短信验证凭证

其中 otp 选项传递一个对象,其唯一选项 transport 接收一个字符串数组,其唯一合法项为 sms

方法返回一个 Promise,其兑现一个 OTPCredential 实例

方法在传入的 signal 选项对应的 AbortSignal 已终止时抛出 AbortError 异常;在方法被权限策略拒绝时抛出 SecurityError 异常

OTPCredential 接口表示短信验证凭证

code 只读属性代表一个字符串,表示收到的短信验证码

1
2
3
4
5
6
7
8
9
10
11
12
navigator.credentials
.get({
otp: {
transport: ["sms"],
},
})
.then((otp) => {
console.log(otp.code)
})
.catch((err) => {
console.error(err)
})

步骤

  1. 首先用户填写其手机号码,网页将其发送到应用服务器
  2. 随后调用 navigator.credentials.get() 方法执行相关操作
  3. 接着应用服务器向指定的手机号发送验证码短信
  4. 随后用户代理会弹窗提醒用户是否允许网页访问验证码
  5. 用户授权后可通过 navigator.credentials.get() 方法执行结果获取到验证码并可将其填写在网页上
  6. 最终填写结果会发送给应用服务器进行验证,并进行后续一些操作

短信格式限制

限制短信最后一行必须以 @ 开头,后接调用 API 的网页的域名;随后以空格分隔,以 # 开头,后接短信验证码

1
2
3
Your verification code is 123456.

@www.example.com #123456

若其在内嵌第三方网页中调用;且第一段需为顶层网页的域名;最后一行还需要增加以 # 开头,后接内嵌第三方网页的域名

1
2
3
Your verification code is 123456.

@top-level.example.com #123456 @embedded.com

替代策略

可以利用 autocomplete 属性的 one-time-code 值在某种程度上提示用户代理自动填充短信验证码

1
<input autocomplete="one-time-code" required/>

权限策略

该 API 调用受到 otp-credentials 权限策略的控制,可以通过 Permissions-Policy 响应头指定,或通过 <iframe> 标签的 allow 属性指定

默认值是 self,即允许同源的浏览上下文使用该 API

类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
interface OTPCredential extends Credential {
readonly code: string
}

interface CredentialRequestOptions {
otp: OTPCredentialRequestOptions
}

interface OTPCredentialRequestOptions {
transport?: OTPCredentialTransportType[]
}

enum OTPCredentialTransportType {
"sms",
}

链接

Credential Management API

Credential Management API 允许网站存储和检索密码、公钥与联合凭证

用户无需显式登录即可直接登录、查看登录站点的联合账户及恢复会话

通用凭证管理

凭证管理主要通过 CredentialsContainer 接口提供的各类方法实现

通过 Navigator 接口的 credentials 只读属性获取其实例

创建凭证

可以直接使用对应凭证具体类型的构造函数创建新凭证

或调用 CredentialsContainer 接口的 create() 方法用于创建新凭证

方法可以传入一个可选的配置项

配置项中 signal 可选参数接收一个 AbortSignal 实例,可用于编程式终止创建进程

此外,必须向配置项中传入 password federated publicKey 中某个选项,以创建对应的具体类型的凭证,具体选项细节见下及 Web Authentication API 内容

方法返回一个 Promise,其兑现一个 Credential 实例,或 null(若无法创建凭证)

相关示例见下具体凭证类型章节

存储凭证

调用 CredentialsContainer 接口的 store() 方法存储凭证

方法需要传入一个 Credential 接口或其子接口的实例,代表需要保存的凭证

方法返回一个 Promise

示例如下所示

1
2
3
4
5
6
7
try {
await navigator.credentials.store(credential)

console.log('success')
} catch {
console.log('failure')
}

读取凭证

调用 CredentialsContainer 接口的 get() 方法用于获取已存储的凭证,从而用于执行身份验证等用途

方法可以传入一个可选的配置项

配置项中 signal 可选参数接收一个 AbortSignal 实例,可用于编程式终止读取进程

配置项中 mediation 可选参数接收 silent optional conditional required 之一,默认为 optional,指定用户是否会在每次访问时请求登录

  • silent 不会要求用户进行身份验证
  • optional 若凭据无需用户中介即可移交,则会直接移交;反之则会要求用户进行身份验证
  • conditional 凭据将会通过非模态对话框提供给用户并指示凭证的来源,其相当于自动填充可用的凭证
  • required 始终要求用户进行登录身份验证

此外,可以向配置项中传入 password federated publicKey otp identity 中多个选项,以仅读取对应的具体类型的凭证,具体选项细节见下及 Web Authentication API、WebOTP API、Federated Credential Management API 等内容

方法返回一个 Promise,其兑现一个 Credential 实例,或 null(若无法读取凭证)

相关示例见下具体凭证类型章节

阻止自动登录

调用 CredentialsContainer 接口的 preventSilentAccess() 方法用于未来访问时阻止自动登录功能

方法返回一个 Promise

此方法可以在用户退出网站时调用,以避免用户登录信息在下次访问时不会自动传递

通用凭证

Credential 抽象接口表示通用凭证,其子接口表示各种具体类型的凭证

Credential 接口的 id 只读属性返回一个字符串,表示凭证的标识符

Credential 接口的 type 只读属性返回一个字符串,表示凭证的具体类型

子接口与类型的映射如下:

子接口 type 属性值
PasswordCredential password
FederatedCredential federated
PublicKeyCredential public-key
OTPCredential otp
IdentityCredential identity

密码凭证

PasswordCredential 接口表示密码凭证

密码凭证信息

PasswordCredential 接口的 iconURL 只读属性返回一个字符串,表示凭证的图标的 URL

PasswordCredential 接口的 name 只读属性返回一个字符串,表示凭证的名称

PasswordCredential 接口的 password 只读属性返回一个字符串,表示凭证所包含的密码

创建密码凭证

可以调用 PasswordCredential() 构造函数创建密码凭证

可以向构造函数传入一个 HTMLFormElement 实例参数

表单至少需要包含 idpassword 字段,可以包含一个 csrf_token 以及 nameiconURL 字段

1
2
3
4
5
6
7
<form id="form">
<label for="id">Username:</label>
<input type="text" name="id" autocomplete="username" />
<label for="password">Password:</label>
<input type="password" name="password" autocomplete="current-password" />
<input type="hidden" name="csrf_token" value="*****" />
</form>
1
2
const form = document.getElementById("form");
const credential = new PasswordCredential(form);

也可以直接向构造函数传入一个配置项参数,至少需要包含 idpasswordorigin 字段,可选传入 nameiconURL 字段

1
2
3
4
5
6
const data = {
id: "xxxxxx",
password: "xxxxxx",
origin: "www.example.com",
};
const credential = new PasswordCredential(data);

亦可以通过 CredentialsContainer 接口的 create() 方法创建密码凭证

需要在配置项中传入 password 选项,其为一个对象,对象结构同传入 PasswordCredential() 构造函数的配置项结构

1
2
3
4
5
6
7
8
navigator.credentials
.create({
password: {
id: "xxxxxx",
password: "xxxxxx",
origin: "www.example.com",
}
})

读取密码凭证

通过 CredentialsContainer 接口的 get() 方法读取密码凭证

需要在配置项中传入 password 选项,其接收一个布尔值,默认为 false

1
2
3
navigator.credentials.get({
password: true,
})

联合凭证

FederatedCredential 接口表示联合凭证

联合凭证信息

FederatedCredential 接口的 iconURL 只读属性返回一个字符串,表示凭证的图标的 URL

FederatedCredential 接口的 name 只读属性返回一个字符串,表示凭证的名称

FederatedCredential 接口的 provider 只读属性返回一个字符串,表示凭证的联合身份提供者的 URL

FederatedCredential 接口的 protocol 只读属性返回一个字符串,表示凭证的联合身份协议

创建联合凭证

可以调用 FederatedCredential() 构造函数创建联合凭证

需要传入一个配置项参数,至少需要包含 idproviderorigin 字段,可选传入 nameiconURLprotocol 字段

1
2
3
4
5
6
const data = {
id: "xxxxxx",
provider: "https://account.google.com",
origin: "www.example.com",
};
const credential = new FederatedCredential(data);

亦可以通过 CredentialsContainer 接口的 create() 方法创建联合凭证

需要在配置项中传入 federated 选项,其为一个对象,对象结构同传入 FederatedCredential() 构造函数的配置项结构

1
2
3
4
5
6
7
8
navigator.credentials
.create({
federated: {
id: "xxxxxx",
provider: "https://account.google.com",
origin: "www.example.com",
}
})

读取联合凭证

通过 CredentialsContainer 接口的 get() 方法读取联合凭证

需要在配置项中传入 federated 选项,其接收一个配置项,需要传入 providers 参数与可选的 protocols 参数,两参数均接收一个字符串数组

1
2
3
4
5
navigator.credentials.get({
federated: {
providers: ["https://account.google.com"],
},
})

类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
interface Navigator {
readonly credentials: CredentialsContainer
}

interface CredentialsContainer {
get(options?: CredentialRequestOptions): Promise<Credential | null>
store(credential: Credential): Promise<undefined>
create(options?: CredentialCreationOptions): Promise<Credential | null>
preventSilentAccess(): Promise<undefined>
}

interface CredentialUserData {
readonly name: string
readonly iconURL: string
}

enum CredentialMediationRequirement {
"silent",
"optional",
"conditional",
"required",
}

interface CredentialRequestOptions {
mediation?: CredentialMediationRequirement
signal?: AbortSignal
}

interface CredentialCreationOptions {
signal?: AbortSignal
}

interface CredentialData {
id: string
}

interface Credential {
readonly id: string
readonly type: string
}

interface PasswordCredential extends Credential, CredentialUserData {
constructor(form: HTMLFormElement): PasswordCredential
constructor(data: PasswordCredentialData): PasswordCredential
readonly password: string
}

interface CredentialRequestOptions {
password?: boolean
}

interface PasswordCredentialData extends CredentialData {
name?: string
iconURL?: string
origin: string
password: string
}

type PasswordCredentialInit = PasswordCredentialData | HTMLFormElement

interface CredentialCreationOptions {
password?: PasswordCredentialInit
}

interface FederatedCredential extends Credential, CredentialUserData {
constructor(data: FederatedCredentialInit): FederatedCredential
readonly provider: string
readonly protocol?: string
}

interface FederatedCredentialRequestOptions {
providers?: string[]
protocols?: string[]
}

interface CredentialRequestOptions {
federated?: FederatedCredentialRequestOptions
}

interface FederatedCredentialInit extends CredentialData {
name?: string
iconURL?: string
origin: string
provider: string
protocol?: string
}

interface CredentialCreationOptions {
federated?: FederatedCredentialInit
}

链接

Sensor APIs

Sensor APIs 提供了一系列的传感器 API, 用以提供网页访问应用传感器的权限

通用传感器

Sensor 抽象接口表示通用传感器,该接口被其他具体传感器接口继承,通常不会直接使用该接口

激活

调用 start() 方法激活传感器

在完全激活后,其 activated 属性值会改变,并触发 activate 事件(返回 Event 事件)

停用

调用 stop() 方法停用传感器

读取数据

在每次读取数据时,会触发 reading 事件(返回 Event 事件)

异常处理

在每次读取数据中触发异常时,会触发 error 事件,并返回一个 SensorErrorEvent 事件,可通过其 error 只读属性读取到对应的 DOMException 实例

相关参数

activated 只读属性指示传感器是否已激活

hasReading 只读属性指示传感器是否已读取数据

timestamp 只读属性指示传感器最近一次读取数据的高精度时间戳

加速度传感器

Accelerometer 接口表示加速度传感器,继承自 Sensor 接口

构造该接口时,除了 Sensor 接口构造函数的 frequency 参数外,还可以额外指定 referenceFrame 参数指示,值可以为 devicescreen 之一,默认值是 device

该接口的 x y z 只读属性分别表示在 x 轴、y 轴和 z 轴上的分加速度

线性加速度传感器

LinearAccelerationSensor 接口表示线性加速度传感器,继承自 Accelerometer 接口

线性加速度指不考虑重力影响下的加速度

重力加速度传感器

GravitySensor 接口表示重力加速度传感器,继承自 Accelerometer 接口

物理方向传感器

OrientationSensor 抽象接口表示物理方向传感器,该接口被其他具体物理方向传感器接口继承,通常不会直接使用该接口

该接口的 quaternion 只读属性返回一个四元数只读元组,表示设备物理方向的四元组(x y z w)的值

该接口的 populateMatrix() 方法使用最新的旋转矩阵填充给定的目标矩阵

绝对物理方向传感器

AbsoluteOrientationSensor 接口表示绝对物理方向传感器,继承自 OrientationSensor 接口

绝对物理方向指相对地球坐标系的物理方向

构造该接口及其子接口时,除了 Sensor 接口构造函数的 frequency 参数外,还可以额外指定 referenceFrame 参数指示,值可以为 devicescreen 之一,默认值是 device

相对物理方向传感器

RelativeOrientationSensor 接口表示相对物理方向传感器,继承自 OrientationSensor 接口

相对物理方向指根据设备决定的物理方向,不考虑地球坐标系

构造该接口及其子接口时,除了 Sensor 接口构造函数的 frequency 参数外,还可以额外指定 referenceFrame 参数指示,值可以为 devicescreen 之一,默认值是 device

环境光传感器

AmbientLightSensor 接口表示环境光传感器,继承自 Sensor 接口

该接口的 illuminance 只读属性返回环境光的强度,单位流明

陀螺仪传感器

Gyroscope 接口表示陀螺仪传感器,继承自 Sensor 接口

构造该接口时,除了 Sensor 接口构造函数的 frequency 参数外,还可以额外指定 referenceFrame 参数指示,值可以为 devicescreen 之一,默认值是 device

该接口的 x y z 只读属性分别表示在 x 轴、y 轴和 z 轴上的分角速度

磁场传感器

Magnetometer 接口表示磁场传感器,继承自 Sensor 接口

构造该接口时,除了 Sensor 接口构造函数的 frequency 参数外,还可以额外指定 referenceFrame 参数指示,值可以为 devicescreen 之一,默认值是 device

该接口的 x y z 只读属性分别表示在 x 轴、y 轴和 z 轴上的分磁场强度

权限策略

该组 API 调用受到 accelerometer gyroscope magnetometer ambient-light-sensor 等权限策略的控制,可以通过 Permissions-Policy 响应头指定,或通过 <iframe> 标签的 allow 属性指定

默认值均是 self,即允许允许在顶层浏览上下文及其同源的嵌入浏览上下文中使用

传感器 权限策略
Accelerometer accelerometer
LinearAccelerationSensor accelerometer
GravitySensor accelerometer
RelativeOrientationSensor accelerometer gyroscope
AbsoluteOrientationSensor accelerometer gyroscope magnetometer
AmbientLightSensor ambient-light-sensor
Gyroscope gyroscope
Magnetometer magnetometer

权限 API

该组 API 调用时需要用户授予 accelerometer gyroscope magnetometer ambient-light-sensor 等权限,可以调用 Permission.query() 方法检查用户是否已授予了该权限

传感器 权限
Accelerometer accelerometer
LinearAccelerationSensor accelerometer
GravitySensor accelerometer
RelativeOrientationSensor accelerometer gyroscope
AbsoluteOrientationSensor accelerometer gyroscope magnetometer
AmbientLightSensor ambient-light-sensor
Gyroscope gyroscope
Magnetometer magnetometer

类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
interface Sensor extends EventTarget {
readonly activated: boolean
readonly hasReading: boolean
readonly timestamp?: DOMHighResTimeStamp

start(): void
stop(): void

onreading: ((this: Sensor, ev: Event) => any) | null
onactivate: ((this: Sensor, ev: Event) => any) | null
onerror: ((this: Sensor, ev: SensorErrorEvent) => any) | null
}

interface SensorOptions {
frequency: number
}

interface SensorErrorEvent extends Event {
constructor(type: string, errorEventInitDict: SensorErrorEventInit)
readonly error: DOMException
}

interface SensorErrorEventInit extends EventInit {
error: DOMException
}

interface Accelerometer extends Sensor {
constructor(options?: AccelerometerSensorOptions)
readonly x?: number
readonly y?: number
readonly z?: number
}

enum AccelerometerLocalCoordinateSystem { "device", "screen" }

interface AccelerometerSensorOptions extends SensorOptions {
referenceFrame?: AccelerometerLocalCoordinateSystem
}

interface LinearAccelerationSensor extends Accelerometer {
constructor(options?: AccelerometerSensorOptions)
}

interface GravitySensor extends Accelerometer {
constructor(options?: AccelerometerSensorOptions)
}

type RotationMatrixType = Float32Array | Float64Array | DOMMatrix

interface OrientationSensor extends Sensor {
readonly quaternion?: ReadonlyArray<number>
populateMatrix(targetMatrix: RotationMatrixType): void
}

enum OrientationSensorLocalCoordinateSystem { "device", "screen" }

interface OrientationSensorOptions extends SensorOptions {
referenceFrame?: OrientationSensorLocalCoordinateSystem
}

interface AbsoluteOrientationSensor extends OrientationSensor {
constructor(sensorOptions?: OrientationSensorOptions)
}

interface RelativeOrientationSensor extends OrientationSensor {
constructor(sensorOptions?: OrientationSensorOptions)
}

interface AmbientLightSensor extends Sensor {
constructor(options?: SensorOptions)
readonly illuminance?: number
}

interface Gyroscope extends Sensor {
constructor(sensorOptions?: GyroscopeSensorOptions)
readonly x?: number
readonly y?: number
readonly z?: number
}

enum GyroscopeLocalCoordinateSystem { "device", "screen" }

interface GyroscopeSensorOptions extends SensorOptions {
referenceFrame?: GyroscopeLocalCoordinateSystem
}

interface Magnetometer : Sensor {
constructor(sensorOptions?: MagnetometerSensorOptions)
readonly x?: number
readonly y?: number
readonly z?: number
}

enum MagnetometerLocalCoordinateSystem { "device", "screen" }

interface MagnetometerSensorOptions extends SensorOptions {
referenceFrame?: MagnetometerLocalCoordinateSystem
}

链接

Remote Playback API

Remote Playback API 允许管理与当前媒体资源连接的远程媒体设备

使用远程媒体设备控制

通过 HTMLMediaElement 接口的 remote 只读属性获取到与当前媒体元素相关的 RemotePlayback 实例

RemotePlayback 接口提供了实际管理与当前媒体资源连接的远程媒体设备的相关属性、方法及事件

状态

RemotePlayback 接口的 state 只读属性返回与当前媒体资源连接的远程媒体设备的状态

其值为以下之一的字符串:

  • connecting 当前媒体资源正在连接到远程媒体设备
  • connected 当前媒体资源已连接到远程媒体设备
  • disconnected 当前媒体资源未连接到远程媒体设备(如尚未初始化,连接失败或连接终止等)

监测可用远程媒体设备

调用 RemotePlayback 接口的 watchAvailability() 方法开始监视可用远程媒体设备

该方法需要传递一个回调方法参数,其在远程媒体设备可用性发生变化时调用,并传入一个代表远程媒体设备可用性的布尔值

该方法返回一个兑现一个代表对应远程媒体设备的 ID 的整数的 Promise

在对应媒体元素的 disableRemotePlayback 属性为 true 时抛出 InvalidStateError 异常

在用户代理不支持持续监听可用远程媒体设备列表时抛出 NotSupportedError 异常

调用 RemotePlayback 接口的 cancelWatchAvailability() 方法取消监视可用远程媒体设备

方法可以可选地传入一个整数,代表对应远程媒体设备的 ID

在对应媒体元素的 disableRemotePlayback 属性为 true 时抛出 InvalidStateError 异常

在传入的代表对应远程媒体设备的 ID 不存在时抛出 NotSupportedError 异常

连接远程媒体设备

调用 RemotePlayback 接口的 prompt() 方法显示弹窗以展示可用的远程媒体设备,用户可选择用于播放当前媒体资源的远程媒体设备并给予权限

方法返回一个 Promise

若对应媒体元素的 disableRemotePlayback 属性为 true,抛出 InvalidStateError 异常

若对应媒体元素上(或浏览上下文)正在调用 prompt() 方法,抛出 OperationError 异常

若用户最近未和网页发生交互,抛出 InvalidAccessError 异常

若用户代理确信远程播放特定媒体不可行,抛出 NotSupportedError 异常

若远程播放不可用,抛出 NotFoundError 异常

若用户选定远程媒体设备并授予权限后:

  • 用户代理会开始连接远程媒体设备
  • 当前媒体元素相关的 RemotePlayback 实例的 state 设定为 connecting
  • 触发 connecting 事件
  • 完成连接后触发 connect 事件

若用户代理选择断开与远程媒体设备的连接

  • 用户代理开始断开与远程媒体设备的连接
  • 当前媒体元素相关的 RemotePlayback 实例的 state 设定为 disconnected
  • 触发 disconnect 事件

在用户代理开始连接远程媒体设备时,触发 connecting 事件

在用户代理连接至远程媒体设备时,触发 connect 事件

在用户代理断开与远程媒体设备的连接时,触发 disconnect 事件

禁用远程媒体设备控制

通过 HTML <audio><video> 媒体元素的 disableremoteplayback 属性设置,或 HTMLMediaElement 元素的 disableRemotePlayback 属性读取或设置是否禁用当前媒体元素的远程播放

类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
interface RemotePlayback extends EventTarget {
readonly state: RemotePlaybackState;
cancelWatchAvailability(id?: number): Promise<void>;
prompt(): Promise<void>;
watchAvailability(callback: RemotePlaybackAvailabilityCallback): Promise<number>;
onconnect: ((this: RemotePlayback, ev: Event) => any) | null;
onconnecting: ((this: RemotePlayback, ev: Event) => any) | null;
ondisconnect: ((this: RemotePlayback, ev: Event) => any) | null;
}

interface HTMLMediaElement {
disableRemotePlayback: boolean;
readonly remote: RemotePlayback;
}

链接

Channel Messaging API

Channel Messaging API 支持在多个浏览上下文中执行的脚本之间传递消息

其核心为 MessageChannel 接口与 MessagePort 接口

消息频道

MessageChannel 接口表示单个消息频道

使用 MessageChannel() 构造函数创建新的 MessageChannel 实例,此时其 port1port2 只读属性均返回一个 MessagePort 实例,表示消息频道的端口

消息端口

MessagePort 接口表示单个消息端口

启动

调用 start() 方法启动消息端口,仅在仅通过 addEventListener() 方法监听事件的情况下预先调用

消息发送

调用 postMessage() 方法向绑定的另外一个消息端口发送消息(或转让可转移对象的所有权)

方法第一个参数表示要发送的消息,接收一个可序列化值

方法第二个参数表示可转移对象,接收一个数组或一个包含 transfer 键的对象

消息接收

message 事件在接收到消息时触发一个 MessageEvent 事件

messageerror 事件在接收到消息但解析失败时触发一个 MessageEvent 事件

停止

调用 close() 方法停止消息端口

类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
interface MessageChannel {
readonly port1: MessagePort
readonly port2: MessagePort
}

declare var MessageChannel: {
prototype: MessageChannel
new(): MessageChannel
}

interface MessagePort extends EventTarget {
close(): void
postMessage(message: any, transfer: Transferable[]): void
postMessage(message: any, options?: StructuredSerializeOptions): void
start(): void
onmessage: ((this: MessagePort, ev: MessageEvent) => any) | null
onmessageerror: ((this: MessagePort, ev: MessageEvent) => any) | null
}

declare var MessagePort: {
prototype: MessagePort
new(): MessagePort
}

链接

浏览器原理

浏览器进程

  1. 主进程 只有一个,负责调度主控整个浏览器
  2. 插件进程 每个插件都有一个进程,只在插件被调用的时候创建
  3. GPU进程 只有一个,负责 3d 绘制
  4. 渲染进程 通常每个标签页一个,负责网页的渲染、脚本的执行和事件的处理等

浏览器渲染进程

  1. GUI 线程 负责页面的构建和渲染,当页面需要被绘制的时候就会启动这个线程,要注意的是该线程和 JS 引擎线程是互斥的,不能并行执行
  2. JS 引擎线程 负责解析和执行 JS 脚本,因为他和GUI线程的互斥性,所以 JS 代码是会导致页面渲染不连贯的,也就是常说的阻塞页面渲染
  3. 事件触发线程 归属于浏览器,而不是 JS 引擎,他主要就是控制事件循环,将一系列的任务加入一个队列等 JS 引擎空闲下来后去执行
  4. 定时器线程 管理定时器的计时,等时间到了就把事件推入任务队列,等待 JS 引擎执行
  5. HTTP 请求线程 每发送一个请求就会开启一个新的线程,等待响应后把回调函数推入任务队列,等 JS 引擎执行。

Autoplay Policy Detection API

Autoplay Policy Detection API 允许获取音频的自动播放模式

该 API 通过 Navigator 接口的 getAutoplayPolicy() 方法提供相关功能

使用

方法可以传入一个字符串,需为 mediaelementaudiocontext 之一;亦可以传入一个 HTMLMediaElement 元素或一个 AudioContext 实例

方法返回一个字符串,值为 allowedallowed-muteddisallowed,分别代表允许自动播放,允许静音状态下的自动播放(仅针对媒体元素而言)以及不允许自动播放

若参数不符合约束时,抛出 TypeError 异常

类型

1
2
3
4
5
6
7
8
interface Navigator {
getAutoplayPolicy(type: AutoplayPolicyMediaType): AutoplayPolicy
getAutoplayPolicy(element: HTMLMediaElement): AutoplayPolicy
getAutoplayPolicy(context: AudioContext): AutoplayPolicy
}

type AutoplayPolicyMediaType = "mediaelement" | "audiocontext"
type AutoplayPolicy = "allowed" | "allowed-muted" | "disallowed"

链接

Background Tasks API

Background Tasks API 允许创建后台任务

这些后台任务会在用户代理认为空闲时执行,从而可以优先执行高级别的任务

使用

使用 Window 接口的 requestIdleCallback() 方法注册后台任务,需要传入一个代表后台任务的回调方法,返回任务 ID

并且,可以可选地传入一个配置项参数,其 timeout 选项指定超时时间;后台任务在达到超时时间后会正常放入任务队列中执行

传入的回调方法在调用时,会传入一个 IdleDeadline 对象,该对象的 didTimeout 只读属性指示是否是因为超时而调用该方法,timeRemaining() 方法返回一个时间戳,指示当前空余任务周期的剩余时间

使用 Window 接口的 cancelIdleCallback() 方法取消之前调用 requestIdleCallback() 注册后台任务,需要传入任务 ID

1
2
3
4
5
6
7
const handle = window.requestIdleCallback(() => {
// to do something
}, {
timeout: 60 * 1000,
})

window.cancelIdleCallback(handle)

类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
interface Window {
cancelIdleCallback(handle: number): void
requestIdleCallback(callback: IdleRequestCallback, options?: IdleRequestOptions): number
}

interface IdleRequestCallback {
(deadline: IdleDeadline): void
}

interface IdleDeadline {
readonly didTimeout: boolean
timeRemaining(): DOMHighResTimeStamp
}

interface IdleRequestOptions {
timeout?: number
}

链接

Web Components API

Web Components API 允许创建并使用自定义 HTML 元素

概述

  • Custom Element,用于定义自定义元素及其行为
  • Shadow DOM,将封装的 Shadow DOM 树附加到元素并避免与文档其他部分产生冲突
  • HTML templates,通过 <template><slot> 元素编写可重用的模板

Custom Element

自定义元素包含两类,一类是基于现有的内置标准元素扩展,主要用于自定义标准元素行为,称为自定义内置元素(Customized built-in element);一类是直接基于 HTMLElement 基类拓展,需要完成实现行为,称为独立自定义元素(Autonomous custom element)

定义

首先需要定义一个类 class,该类需要继承自 HTMLElement 或者其他内置标准元素

1
2
3
4
5
6
7
8
9
10
11
class CustomElement extends HTMLElement {
constructor() {
super()
}
}

class CustomParagraphElement extends HTMLParagraphElement {
constructor() {
super()
}
}

在构造函数中设置初始状态及默认值,注册事件监听器,或者创建一个影子根元素;此阶段不应当尝试读取或修改元素的属性或其子元素

生命周期回调方法

在注册组件后,在发生一些特定事件时,会触发对应的生命周期回调方法,包括如下几种:

  • connectedCallback() 在每次元素被添加到文档中时调用;标准建议在该回调中实现自定义元素的初始化
  • disconnectedCallback() 在每次元素从文档中移除时调用
  • adoptedCallback() 在每次元素被移动到新文档时调用
  • attributeChangedCallback() 在监视的属性增加、移除、修改、替换时调用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class CustomElement extends HTMLElement {
static observedAttributes = ["size"]

constructor() {
super()
}

connectedCallback() {
console.log("Custom element added to page")
}

disconnectedCallback() {
console.log("Custom element removed from page")
}

adoptedCallback() {
console.log("Custom element moved to new page")
}

attributeChangedCallback(name, oldValue, newValue) {
console.log(`Attribute ${name} has changed`)
}
}

注册

定义自定义元素后,还需要将其注册到文档中,才可使用

是通过 CustomElementRegistry 接口的 define() 方法实现,该实例通过 Window 接口的 customElements 只读属性暴露

该方法可以接受 2 - 3 个参数:

第一个参数接收一个字符串,表示该自定义元素的名称,要求:必须以小写字母开头且包含连字符

第二个参数接收一个构造函数,表示该自定义元素本身的构造函数

第三个可选参数接收一个可选的对象,仅允许对扩展内置标准元素的自定义元素指定,包含 extends 参数,表示由其继承的内置标准元素的名称

1
2
3
window.customElements.define("custom-paragraph-element", CustomParagraphElement, { extends: "p" })

window.customElements.define("custom-element", CustomElement)

使用

若为自定义内置元素,在扩展的内置标准元素上指定全局 is 属性

1
<p is="custom-paragraph-element"></p>

若为独立自定义元素,直接以类似标准元素的方式使用即可

1
<custom-element></custom-element>

监听属性变化

自定义元素类似原生内置标准元素一样,也使用属性传递信息

要监听属性变化(包括首次初始化),需要通过指定 observedAttributes 静态属性,其接收一个字符串数组

自定义伪类

可以在自定义元素中通过 HTMLElement 接口的 attachInternals() 方法获取到的 ElementInternals 接口实例,通过其 states 属性返回的 CustomStateSet 实例,添加或移除伪类状态

仅限于独立自定义元素使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class MyCustomElement extends HTMLElement {
constructor() {
super()
this.internals = this.attachInternals()
}

get collapsed() {
return this.internals.states.has("--hidden")
}

set collapsed(flag) {
if (flag) {
this.internals.states.add("--hidden")
} else {
this.internals.states.delete("--hidden")
}
}
}

Shadow DOM

概念

  • 影子宿主(Shadow host) 影子 DOM 附加到的常规 DOM 节点
  • 影子树(Shadow tree) 影子 DOM 内部的 DOM 树
  • 影子边界(Shadow boundary) 影子 DOM 终止,常规 DOM 开始的地方
  • 影子根节点(Shadow root) 影子树的根节点

在影子树内与影子树外通常是相互隔离的

模式

在调用 Element 接口的 attachShadow() 方法获取影子根节点时,可以传递一个 mode 参数,控制影子树内部是否对外部开放

允许的值为 openclose

若指定为 open,外部的脚本可以通过影子宿主的 shadowRoot 属性访问影子树内部

样式

向影子树中添加样式有两种方式:

一种通过新建 CSSStyleSheet 并向其添加样式,再将其附加到影子根节点

另外一种是通过新建 <style> 标签,并修改其内容,再将其附加到影子树

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class CustomElement extends HTMLElement {
constructor() {
super()
}
connectedCallback() {
const shadow = this.attachShadow({ mode: "open" })

const sheet = new CSSStyleSheet()
sheet.replaceSync("span { color: red; border: 2px dotted black;}")
shadow.adoptedStyleSheets.push(sheet)

const style = document.createElement('style')
style.sheet.replaceSync("span { color: red; border: 2px dotted black;}")
shadow.appendChild(style)
}
}

与自定义元素使用

自定义元素的核心正是 ShadowRoot 技术,其保证了自定义元素的封装能力

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class CustomElement extends HTMLElement {
constructor() {
super()
}
connectedCallback() {
const shadow = this.attachShadow({ mode: "open" })

const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg")
const circle = document.createElementNS("http://www.w3.org/2000/svg", "circle")
circle.setAttribute("cx", "50")
circle.setAttribute("cy", "50")
circle.setAttribute("r", "50")
circle.setAttribute("fill", this.getAttribute("color"))
svg.appendChild(circle)

shadow.appendChild(svg)
}
}

HTML templates

使用 template

可以使用 <template> 声明一组 DOM 结构,该 DOM 结构不会在页面中显示,直至手动获取其内容并插入到其他 DOM 结构中

使用 slot

可以使用 <slot> 声明在模板中,代表一个占位符,并为其指定 name 属性,代表其名称

在使用模板时,可以通过向模板中的特定元素指定 slot 属性,并指定为期望替换的占位符的名称,此时指定的元素便会替代模板中对应占位符位置的元素

链接


:D 一言句子获取中...