DeviceOrientation Event

DeviceOrientation Event 允许监测设备的物理朝向及物理加速度

物理加速度

Window 接口的 devicemotion 事件在设备的物理加速度(及旋转速率)变化时定期触发,返回一个 DeviceMotionEvent 事件

1
2
3
window.addEventListener('devicemotion', (e) => {
//
})

DeviceMotionEvent 接口的 acceleration 属性返回一个 DeviceMotionEventAcceleration 实例,表示设备的加速度(包含 x y z 三个参数)

DeviceMotionEvent 接口的 accelerationIncludingGravity 属性返回一个 DeviceMotionEventAcceleration 实例,表示受重力影响下设备的加速度(包含 x y z 三个参数)

DeviceMotionEvent 接口的 rotationRate 属性返回一个 DeviceMotionEventRotationRate 实例,表示设备的旋转角速度(包含 alpha beta gamma 三个参数)

DeviceMotionEvent 接口的 interval 属性返回一个 number,表示设备更新数据的间隔

物理朝向

Window 接口的 deviceorientation 事件在设备的物理朝向变化时定期触发,返回一个 DeviceOrientationEvent 事件

Window 接口的 deviceorientationabsolute 事件在设备的绝对物理朝向变化时触发,返回一个 DeviceOrientationEvent 事件

1
2
3
4
5
6
7
window.addEventListener('deviceorientation', (e) => {
//
})

window.addEventListener('deviceorientationabsolute', (e) => {
//
})

DeviceOrientationEvent 接口的 absolute 属性返回一个 boolean,表明当前是否提供绝对方向数据(地球坐标系),或设备任意坐标系

DeviceOrientationEvent 接口的 alpha 属性返回一个范围在 0360 之间的 number,表明设备绕 z 轴旋转的角度

DeviceOrientationEvent 接口的 beta 属性返回一个范围在 -180180 之间的 number,表明设备绕 x 轴旋转的角度

DeviceOrientationEvent 接口的 gamma 属性返回一个范围在 -9090 之间的 number,表明设备绕 y 轴旋转的角度

权限策略

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

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

deviceorientation 事件与 devicemotion 事件需要 accelerometer gyroscope 权限策略,而 deviceorientationabsolute 事件需要 accelerometer gyroscope magnetometer 权限策略

权限 API

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

deviceorientation 事件与 devicemotion 事件需要授予 accelerometer gyroscope 权限,而 deviceorientationabsolute 事件需要授予 accelerometer gyroscope 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
interface Window {
ondeviceorientation: ((this: Window, ev: DeviceOrientationEvent) => any) | null
ondeviceorientationabsolute: ((this: Window, ev: DeviceOrientationEvent) => any) | null
ondevicemotion: ((this: Window, ev: DeviceMotionEvent) => any) | null
}

interface DeviceOrientationEvent extends Event {
readonly alpha: number | null
readonly beta: number | null
readonly gamma: number | null
readonly absolute: boolean
}

declare var DeviceOrientationEvent: {
new (type: string, eventInitDict?: DeviceOrientationEventInit): DeviceOrientationEvent
prototype: DeviceOrientationEvent

requestPermission(): Promise<PermissionState>
}

interface DeviceOrientationEventInit extends EventInit {
alpha?: number | null
beta?: number | null
gamma?: number | null
absolute?: boolean
}

interface DeviceMotionEventAcceleration {
readonly x: number | null
readonly y: number | null
readonly z: number | null
}

interface DeviceMotionEventRotationRate {
readonly alpha: number | null
readonly beta: number | null
readonly gamma: number | null
}

interface DeviceMotionEvent extends Event {
readonly acceleration: DeviceMotionEventAcceleration | null
readonly accelerationIncludingGravity: DeviceMotionEventAcceleration | null
readonly rotationRate: DeviceMotionEventRotationRate | null
readonly interval: number
}

declare var DeviceMotionEvent: {
new (type: string, eventInitDict?: DeviceMotionEventInit): DeviceMotionEvent
prototype: DeviceMotionEvent

requestPermission(): Promise<PermissionState>
}

interface DeviceMotionEventAccelerationInit {
x?: number | null
y?: number | null
z?: number | null
}

interface DeviceMotionEventRotationRateInit {
alpha?: number | null
beta?: number | null
gamma?: number | null
}

interface DeviceMotionEventInit extends EventInit {
acceleration?: DeviceMotionEventAccelerationInit
accelerationIncludingGravity?: DeviceMotionEventAccelerationInit
rotationRate?: DeviceMotionEventRotationRateInit
interval?: number
}

链接

Contact Picker API

Contact Picker API 允许用户从通讯录选择记录并与网页应用分享

该 API 通过 ContactsManager 接口使用,并通过 Navigator.contacts 向用户暴露

检测支持的参数

调用 ContactsManager 接口的 getProperties() 方法以获取当前设备支持的参数列表

方法返回 Promise 的字符串列表,值具体在 "address" "email" "icon" "name" "tel" 之中,代表设备通讯录支持的参数类型

1
const properties = await navigator.contacts.getProperties()

获取通讯录记录

调用 ContactsManager 接口的 select() 方法以获取通讯录记录

方法接收一个字符串数组,值需要在 "address" "email" "icon" "name" "tel" 之中,代表需要获取的通讯录记录的参数

方法可以接收一个可选的配置项参数,其 multiple 选项指定是否支持选择多条记录,默认 false

方法返回一个对象数组,代表获取到的通讯录记录;数组各项均包含 "address" "email" "icon" "name" "tel" 字段

若方法未在顶层浏览上下文调用,或当前已有其他该方法的调用,或启动通讯录选择器失败,则抛出 InvalidStateError 异常

若方法非因为用户交互调用,则抛出 SecurityError 异常

若方法传入一个空数组,或传入的数组任一项当前设备不支持,则抛出 TypeError 异常

1
const contacts = await navigator.contacts.select(properties)

通讯录记录细节

  • "address" 返回 ContactAddress 数组,代表各记录的地址

  • "email" 返回 string 数组,代表各记录的邮箱

  • "icon" 返回 Blob 数组,代表各记录的图标

  • "name" 返回 string 数组,代表各记录的名称

  • "tel" 返回 string 数组,代表各记录的电话

类型

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
interface Navigator {
readonly contacts: ContactsManager
}

type ContactProperty = "address" | "email" | "icon" | "name" | "tel"

interface ContactAddress {
toJSON(): Object
readonly city: string
readonly country: string
readonly dependentLocality: string
readonly organization: string
readonly phone: string
readonly postalCode: string
readonly recipient: string
readonly region: string
readonly sortingCode: string
readonly addressLine: string[]
}

interface ContactInfo {
address: ContactAddress[]
email: string[]
icon: Blob[]
name: string[]
tel: string[]
}

interface ContactsSelectOptions {
multiple?: boolean
}

interface ContactsManager {
getProperties(): Promise<ContactProperty[]>
select(properties: ContactProperty[], options?: ContactsSelectOptions): Promise<ContactInfo[]>
}

链接

Cookie Store API

Cookie Store API 提供了异步地管理 Cookie 的方式,同时允许在 ServiceWorker 中使用

在该 API 之前,使用 cookie 的方式是通过读写 document.cookie 属性,但其是单线程同步的,可能会阻碍事件循环;并且其无法在 ServiceWorker 中使用

Window 环境中通过 Window 接口的 cookieStore 属性使用

Window 环境中通过 ServiceWorkerGlobalScope 接口的 cookieStore 属性使用

1
2
window.cookieStore
self.cookieStore

CookieStore 接口的 get() 方法用于获取单条 Cookie

方法接收一个字符串,代表 Cookie 的名称;或接收一个对象,其 name 参数与 url 参数均需指定

方法返回一个 Promise 的 CookieListItem 结构,代表匹配到的 Cookie 信息;反之返回 undefined

1
2
3
4
5
const cookie = await window.cookieStore.get('cookie')
const cookie = await window.cookieStore.get({
name: 'cookie',
url: 'https://www.example.com',
})

CookieStore 接口的 getAll() 方法用于获取单条 Cookie

方法接收一个字符串,代表 Cookie 的名称;或接收一个对象,其 name 参数与 url 参数均需指定

方法返回一个 Promise 的 CookieList 结构,代表匹配到的所有 Cookie

1
2
3
4
5
const cookies = await window.cookieStore.getAll('key')
const cookies = await window.cookieStore.getAll({
name: 'key',
url: 'https://www.example.com',
})

CookieStore 接口的 set() 方法用于设置 Cookie

方法可以接收两个字符串,分别代表 Cookie 的名称与值;亦可以接收一个配置项,各项如下所示:

  • name 属性必需
  • value 属性必需
  • expires 属性可选,默认 null
  • domain 属性可选,默认 null
  • path 属性可选,默认 "/"
  • sameSite 属性可选,默认 "strict"
  • partitioned 属性可选,默认 false

方法返回一个 Promise

1
2
3
4
5
6
7
8
9
10
await window.cookieStore.set('key', 'value')
await window.cookieStore.set({
name: 'key',
value: 'value',
expires: null,
domain: null,
path: '/',
sameSite: 'strict',
partitioned: false,
})

CookieStore 接口的 delete() 方法用于移除 Cookie

方法接收一个字符串,代表 Cookie 的名称;或接收一个对象,其 name 参数必需指定;path 参数 domain 参数 partitioned 参数可选

方法返回一个 Promise

1
2
3
4
5
6
7
await window.cookieStore.delete('key')
await window.cookieStore.delete({
name: 'key',
path: '/',
domain: null,
partitioned: false,
})

CookieList 结构相当于 CookieListItem 结构的数组

CookieListItem 结构反映了 Cookie 的详细信息

CookieListItem 结构的 name 属性返回一个字符串,代表 Cookie 的名称

CookieListItem 结构的 value 属性返回一个字符串,代表 Cookie 的值

CookieListItem 结构的 domain 属性返回一个字符串,代表 Cookie 的域,该属性可能返回 null

CookieListItem 结构的 path 属性返回一个字符串,代表 Cookie 的路径

CookieListItem 结构的 expires 属性返回一个数字,代表 Cookie 的过期时间,该属性可能返回 null

CookieListItem 结构的 secure 属性返回一个布尔值,代表 Cookie 的严格上下文策略

CookieListItem 结构的 sameSite 属性返回一个字符串,代表 Cookie 的同域策略,为 "strict" "lax" "none" 之一

CookieListItem 结构的 partitioned 属性返回一个布尔值,代表 Cookie 的分区策略

CookieStore 接口的 change 事件在任一 Cookie 变化时触发,返回一个 CookieChangeEvent 事件

CookieChangeEvent 接口的 changed 属性返回一个 CookieListItem 结构只读数组,表示被修改的 Cookie

CookieChangeEvent 接口的 deleted 属性返回一个 CookieListItem 结构只读数组,表示被移除的 Cookie

1
2
3
4
window.cookieStore.addEventListener('change', (e) => {
e.changed
e.deleted
})

但该事件仅在 Window 环境中可用

ServiceWorker 中允许通过 CookieStoreManager 接口的方法动态控制 Cookie 变化的订阅

可通过 ServiceWorkerRegistration 接口的 cookies 属性获取到 CookieStoreManager 实例

1
self.registration.cookies

获取订阅

CookieStoreManager 接口的 getSubscriptions() 方法用于获取当前所有的订阅

方法返回一个对象数组,数组各项包含 name 参数和 url 参数

1
const subscriptions = await self.registration.cookies.getSubscriptions()

添加订阅

CookieStoreManager 接口的 subscribe() 方法用于添加订阅

方法传入一个对象数组参数,各项的 name 参数与 url 参数均需指定

方法返回一个 Promise

1
2
3
4
5
6
self.registration.cookies.subscribe([
{
name: 'key',
url: '/',
},
])

移除订阅

CookieStoreManager 接口的 unsubscribe() 方法用于移除订阅

方法传入一个对象数组参数,各项的 name 参数与 url 参数均需指定

方法返回一个 Promise

1
2
3
4
5
6
self.registration.cookies.unsubscribe([
{
name: 'key',
url: '/',
},
])

ServiceWorkerGlobalScope 接口的 cookiechange 事件在订阅的 Cookie 发生变化时触发,返回一个 ExtendableCookieChangeEvent 事件

ExtendableCookieChangeEvent 接口的 changed 属性返回一个 CookieListItem 结构只读数组,表示被修改的 Cookie

ExtendableCookieChangeEvent 接口的 deleted 属性返回一个 CookieListItem 结构只读数组,表示被移除的 Cookie

1
2
3
4
self.addEventListener('cookiechange', (e) => {
e.changed
e.deleted
})

示例

类型

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 CookieStore extends EventTarget {
get(name: string): Promise<CookieListItem | undefined>
get(options?: CookieStoreGetOptions): Promise<CookieListItem | undefined>

getAll(name: string): Promise<CookieList>
getAll(options?: CookieStoreGetOptions): Promise<CookieList>

set(name: string, value: string): Promise<undefined>
set(options: CookieInit): Promise<undefined>

delete(name: string): Promise<undefined>
delete(options: CookieStoreDeleteOptions): Promise<undefined>

onchange: ((this: CookieStore, ev: CookieChangeEvent) => any) | null
}

interface CookieStoreGetOptions {
name: string
url: string
}

enum CookieSameSite {
"strict",
"lax",
"none"
}

interface CookieInit {
name: string
value: string
expires?: DOMHighResTimeStamp | null
domain?: string | null
path?: string
sameSite?: CookieSameSite
partitioned?: boolean
}

interface CookieStoreDeleteOptions {
name: string
domain?: string | null
path?: string
partitione?: boolean
}

interface CookieListItem {
name: string
value: string
domain?: string
path: string
expires?: DOMHighResTimeStamp
secure: boolean
sameSite: CookieSameSite
partitioned: boolean
}

type CookieList = Array<CookieListItem>

interface CookieStoreManager {
subscribe(subscriptions: Array<CookieStoreGetOptions>): Promise<undefined>
getSubscriptions(): Promise<Array<CookieStoreGetOptions>>
unsubscribe(subscriptions: Array<CookieStoreGetOptions>): Promise<undefined>
}

interface ServiceWorkerRegistration {
readonly cookies: CookieStoreManager
}

interface CookieChangeEvent extends Event {
constructor(type: string, eventInitDict?: CookieChangeEventInit)
readonly changed: ReadonlyArray<CookieListItem>
readonly deleted: ReadonlyArray<CookieListItem>
}

interface CookieChangeEventInit extends EventInit {
changed: CookieList
deleted: CookieList
}

interface ExtendableCookieChangeEvent extends ExtendableEvent {
constructor(type: string, eventInitDict?: ExtendableCookieChangeEventInit)
readonly changed: ReadonlyArray<CookieListItem>
readonly deleted: ReadonlyArray<CookieListItem>
}

interface ExtendableCookieChangeEventInit extends ExtendableEventInit {
changed: CookieList
deleted: CookieList
}

interface Window {
readonly cookieStore: CookieStore
}

interface ServiceWorkerGlobalScope {
readonly cookieStore: CookieStore

oncookiechange: ((this: ServiceWorkerGlobalScope, ev: ExtendableCookieChangeEvent) => any) | null
}

链接

User-Agent Client Hints API

User-Agent Client Hints API 扩展了 HTTP Client Hints 以提供允许 JavaScript API 读取浏览器和操作系统信息的方式

该 API 通过 NavigatorUAData 接口提供相关功能,并通过 navigator.userAgentData 暴露

读取基本信息

NavigatorUAData 接口的 brands 属性返回一个 object array,代表浏览器信息,各项包含 brand 属性和 version 属性,均为字符串,分别代表浏览器的名称和版本

NavigatorUAData 接口的 mobile 属性返回一个 boolean,代表当前设备是否为移动端设备

NavigatorUAData 接口的 platform 属性返回一个 string,代表当前设备的操作系统名称

NavigatorUAData 接口的 toJSON() 方法返回一个 JSON 对象,表示可序列化的浏览器的信息

读取细节信息

NavigatorUAData 接口的 getHighEntropyValues() 方法获取浏览器的详细信息

方法传入一个 string array 参数,值允许为 architecture bitness formFactor fullVersionList model platformVersion uaFullVersion wow64 之一

方法返回一个 Promise 的 object,根据参数不同,值可能包含 architecture bitness brands formFactor fullVersionList mobile model platform platformVersion uaFullVersion wow64 等项

方法可能抛出 NotAllowedError,若用户代理认为任一参数不应当被返回

类型

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
interface NavigatorUABrandVersion {
brand: string
version: string
}

interface UADataValues {
architecture: string
bitness: string
brands: NavigatorUABrandVersion[]
formFactor: string[]
fullVersionList: NavigatorUABrandVersion[]
model: string
mobile: boolean
platform: string
platformVersion: string
/** @deprecated */ uaFullVersion: string
wow64: boolean
}

interface UALowEntropyJSON {
brands: NavigatorUABrandVersion[]
mobile: boolean
platform: string
}

interface NavigatorUAData {
readonly brands: ReadonlyArray<>
readonly mobile: boolean
readonly platform: string
getHighEntropyValues(hints: string[]): Promise<UADataValues>
toJSON(): UALowEntropyJSON
}

interface NavigatorUA {
readonly userAgentData: NavigatorUAData
}

interface Navigator extends NavigatorUA {}
interface WorkerNavigator extends NavigatorUA {}

链接

Prioritized Task Scheduling API

Prioritized Task Scheduling API 提供了标准化的任务的优先级排序的方式

通过该 API 能够设定和改变任务优先级,延迟将任务添加至调度程序,终止任务或监听任务优先级改变事件

该 API 定义的任务优先级分类是比较粗糙的,开发者可以根据需要自定义更加细化的任务优先级分类

该 API 通过 scheduler 全局属性暴露 Scheduler 实例使用

创建任务

调用 Scheduler 接口的 postTask() 方法以创建任务

方法传入一个回调函数,代表该任务的内容

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

priority 选项指定任务的优先级,接收一个字符串,值为 user-blocking user-visible background,默认值为 user-visible

signal 选项提供任务的控制器,可以为一个 TaskSignalAbortSignal,用于终止任务或调整任务优先级

delay 选项指定任务添加至任务队列的延迟时间,默认为 0

方法的返回值是一个 Promise,其具体值取决于回调函数的返回值或抛出的异常

1
2
3
4
5
6
7
8
9
scheduler.postTask(() => 'a task', {
priority: 'user-visible',
})
.then((result) => {
console.log('execute success with:', result)
})
.catch((error) => {
console.error('execute fail with:', error)
})

任务优先级

user-blocking 优先级最高,表明该任务可能阻止用户与网页交互

user-visible 优先级一般,表面该任务会让用户察觉但不致阻止用户与网页交互

background 优先级最低,表面该用户不会对用户产生影响

任务的执行顺序优先按任务优先级执行,其次按照定义顺序执行

延迟任务

在任务创建时向 delay 选项传入一个正整数

1
2
3
scheduler.postTask(() => 'a task', {
delay: 1000,
})

终止任务

在任务创建时向 signal 选项传入一个 TaskSignalAbortSignal 参数

在必要时候调用 AbortControllerTaskControllerabort() 方法以终止任务

1
2
3
4
5
6
7
const controllor = new AbortController()

scheduler.postTask(() => 'a task', {
signal: controllor.signal,
})

controllor.abort()

更改任务优先级

在任务创建时向 signal 选项传入一个 TaskSignal 参数

在必要时候调用 TaskControllersetPriority() 方法以重新设置任务的优先级

1
2
3
4
5
6
7
const controller = new TaskController()

scheduler.postTask(() => 'a task', {
signal: controllor.signal,
})

controller.setPriority("background")

调用 TaskController() 构造函数创建一个 TaskController 实例

构造函数接收一个可选的配置项,其参数 priority 指定初始的任务优先级,默认值为 "user-visible"

TaskController 接口的 signal 属性返回一个 TaskSignal 实例,反映与当前 TaskController 相对的 TaskSignal 实例

使用 TaskController 接口的 setPriority() 方法更改当前任务的优先级

方法接收一个字符串,代表任务新的优先级

此外,TaskSignal 实例的 priority 只读属性反映 signal 对应的任务的优先级

TaskSignal 实例的 prioritychange 事件在 signal 对应的任务的优先级改变时触发,返回一个 TaskPriorityChangeEvent 事件,其 previousPriority 参数指定改变前的任务的优先级

1
2
3
4
controller.signal.addEventListener("prioritychange", (e) => {
console.log('previous', e.previousPriority)
console.log('current', controller.signal.priority /* 或 e.target.priority */)
})

输入检测

Scheduling 接口提供了管理计划任务的方法,通过 navigator.scheduling 属性暴露

Scheduling 接口的 isInputPending() 方法判断当前事件队列中是否有输入事件,该方法可以用于判断用户是否在与网页交互

方法接收一个可选的配置项,其参数 includeContinuous 代表是否需考虑持续性触发的事件

方法返回一个 boolean

1
2
3
const flag = navigator.scheduling.isInputPending({
includeContinuous: false,
})

类型

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
type TaskPriority = "user-blocking" | "user-visible" | "background"

interface SchedulerPostTaskOptions {
signal?: AbortSignal
priority?: TaskPriority
delay?: number
}

type SchedulerPostTaskCallback = Function

interface Scheduler {
postTask(callback: SchedulerPostTaskCallback, options?: SchedulerPostTaskOptions): Promise<any>
}

interface TaskPriorityChangeEvent extends Event {
constructor(type: string, priorityChangeEventInitDict: TaskPriorityChangeEventInit)

readonly previousPriority: TaskPriority
}

interface TaskPriorityChangeEventInit extends EventInit {
previousPriority: TaskPriority
}

interface TaskControllerInit {
priority: TaskPriority
}

interface TaskController extends AbortController {
constructor(init: TaskControllerInit)

setPriority(priority: TaskPriority): void
}

interface TaskSignal extends AbortSignal {
readonly priority: TaskPriority

onprioritychange: ((this: TaskSignal, ev: TaskPriorityChangeEvent) => any) | null
}

interface WindowOrWorkerGlobalScope {
readonly scheduler: Scheduler
}

interface Navigator {
readonly scheduling: Scheduling
}

interface Scheduling {
isInputPending(isInputPendingOptions?: IsInputPendingOptions): boolean
}

interface IsInputPendingOptions {
includeContinuous: boolean
}

链接

Screen Orientation API

Screen Orientation API 允许获取屏幕朝向信息和监听屏幕朝向信息变化

该 API 通过 ScreenOrientation 接口提供服务,并通过 window.screen.orientation 暴露该接口的实例

获取屏幕朝向信息

ScreenOrientation 接口的 type 只读属性返回一个字符串,表示当前屏幕朝向的类型,值为 portrait-primary portrait-secondary landscape-primary landscape-secondary 之一

ScreenOrientation 接口的 angel 只读属性返回一个数字,表示当前屏幕朝向的角度

监听屏幕朝向信息变化

ScreenOrientation 接口的 change 事件在当前屏幕朝向变化时触发,返回一个 Event

锁定屏幕朝向信息变化

ScreenOrientation 接口的 lock() 方法锁定系统默认的屏幕朝向变化

方法传入一个字符串参数,代表锁定的类型,值可以为 any landscape landscape-primary landscape-secondary natural portrait portrait-primary portrait-secondary 之一

方法返回一个 Promise

1
await window.screen.orientation.lock('any')

ScreenOrientation 接口的 unlock() 方法解除锁定系统默认的屏幕朝向变化

1
window.screen.orientation.unlock()

沙箱策略

该 API 在 <iframe> 标签中的调用受到 allow-orientation-lock 沙箱策略的控制,需要将 sandbox 的属性指定为允许

类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
interface Screen {
readonly orientation: ScreenOrientation
}

interface ScreenOrientation extends EventTarget {
readonly angle: number
readonly type: OrientationType
onchange: ((this: ScreenOrientation, ev: Event) => any) | null
lock(orientation: OrientationLockType): Promise<void>
unlock(): void
}

type OrientationLockType = "any" | "landscape" | "landscape-primary" | "landscape-secondary" | "natural" | "portrait" | "portrait-primary" | "portrait-secondary"

type OrientationType = "landscape-primary" | "landscape-secondary" | "portrait-primary" | "portrait-secondary"

链接

Storage Access API

Storage Access API 允许第三方上下文中跨站内容(如嵌入 <iframe> 标签中)获取对未分区 cookie (即以传统方式存储的 cookie,仅允许在第一方上下文(直接加载在浏览器选项卡中)中访问)的访问权限

通常出于隐私性考虑,默认用户代理会阻止第三方上下文中跨站内容对未分区 cookie 的访问,但一些场景下,开发者期望启用第三方内容对未分区 cookie 访问的功能

Document 接口的 requestStorageAccess() 方法用于请求文档访问第三方 Cookie 权限

方法返回一个 Promise

方法可能抛出 InvalidStateError 异常,若当前文档尚未进入 active 状态

方法可能抛出 NotAllowedError 异常,若当前文档未处于安全上下文状态,或受权限策略阻止,或当前文档或其顶层文档的 origin 为空,或受 <iframe> 标签沙箱策略的限制,或请求权限被拒绝(如之前已被拒绝,或当前未处于用户激活状态且未授予权限)

1
2
3
4
5
document.requestStorageAccess().then(() => {
console.log('granted')
}).catch(() => {
console.log('denied')
})

Document 接口的 hasStorageAccess() 方法用于检测文档访问第三方 Cookie 权限

方法返回一个 Promise 的 boolean,表示是否已允许文档访问第三方 Cookie

方法可能抛出 InvalidStateError 异常,若当前文档尚未进入 active 状态

1
2
3
4
5
6
7
document.hasStorageAccess().then((sym) => {
if (sym) {
console.log('has access')
} else {
console.log('not has access')
}
})

沙箱策略

该 API 在 <iframe> 标签中的调用受到 allow-storage-access-by-user-activation 沙箱策略的控制,需要将 sandbox 的属性指定为允许

(同时为使用该 API,也需要指定 allow-scriptsallow-same-origin 沙箱策略)

权限策略

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

默认值是 *,即允许任意源的浏览上下文使用该 API

权限 API

该 API 调用需要用户授予 storage-access 权限,可以调用 Permission.query() 方法检查用户是否已授予了该权限

类型

1
2
3
4
interface Document {
hasStorageAccess(): Promise<boolean>
requestStorageAccess(): Promise<undefined>
}

链接

Storage API

Storage API 提供了多个存储 API 的共享的管理方法,允许获取存储的信息并控制存储的清除策略

通常管理的存储包括包括 IndexedDB 、 Cache Storage 、 ServiceWorker 脚本 、 Origin Private File System

该 API 通过 StorageManager 接口提供相关方法,并通过 navigator.storage 对开发者暴露

获取存储信息

StorageManager 接口的 estimate() 方法用于获取用户代理存储的信息

方法返回一个 Promise 的对象,其 usage 属性返回一个数字,代表当前网页使用的存储的大小;quota 属性返回一个数字,代表当前用户代理能为网页提供的存储的大小

1
2
3
4
const storage = await navigator.storage.estimate()

console.log('usage', storage.usage)
console.log('quota', storage.quota)

设置存储清除策略

默认存储策略为 "best-effort",即用户代理会尽可能地保存存储数据,但若需要清除时不会告知用户

而存储策略 "persistent",即用户代理会尽可能地保存存储数据,优先清除存储策略设置为 "best-effort" 的存储,但若需要清除时会主动告知用户

StorageManager 接口的 persisted() 方法检测是否已将存储策略更改为 "persistent",返回一个 Promise 的 boolean

StorageManager 接口的 persist() 方法用于将存储策略更改为 "persistent",返回一个 Promise 的 boolean

1
2
3
4
5
6
7
const result = await navigator.storage.persist()

if (result) {
console.log('persisted')
} else {
console.log('not persisted')
}

权限 API

该 API 调用需要用户 persistent-storage 授予权限,可以调用 Permission.query() 方法检查用户是否已授予了该权限

类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
interface NavigatorStorage {
readonly storage: StorageManager
}

interface Navigator extends NavigatorStorage {}

interface WorkerNavigator extends NavigatorStorage {}

interface StorageManager {
persisted(): Promise<boolean>
persist(): Promise<boolean>

estimate(): Promise<StorageEstimate>
}

interface StorageEstimate {
usage: number
quota: number
}

链接

Permissions API

Permissions API 提供了编程式地检测当前浏览上下文 API 权限

可以用于确定对应的 API 是否已授予权限或被拒绝授予权限,或等待授权权限

同时 API 还会考虑其他因素,如若该 API 对 Secure Context 的要求、Permissions-Policy 的限制等待

该 API 通过 Permissions 接口提供相关功能,并通过 Navigator.permissionsWorkerNavigator.permissions 对外暴露 Permissions 实例

检测权限

调用 Permissions 接口的 query() 方法检测给定 API 的权限状态

方法传入一个 permissionDescriptor 的配置项,其唯一参数 name 反映与给定 API 相关的名称

方法返回一个 Promise 的 PermissionStatus,代表与给定 API 相关的权限状态

1
2
3
4
5
const status = await navigator.permissions.query({
name: 'geolocation',
})

console.log(status.state) // 'granted' 'denied' 'prompt'

PermissionStatusstate 属性返回一个 string,代表权限的状态,为 'granted' 'denied' 'prompt' 之一

PermissionStatusname 属性返回一个 string,代表权限的名称,与 query() 方法传入的 name 参数一致

PermissionStatuschange 事件在权限的状态改变时触发,返回一个 Event

权限名称列表

Permission name Permission description
accelerometer Sensor APIs
ambient-light-sensor Sensor APIs
background-sync Background Synchronization API
camera Media Capture and Streams API
clipboard-read Clipboard API
clipboard-write Clipboard API
geolocation Geolocation API
gyroscope Sensor APIs
local-fonts Local Font Access API
magnetometer Sensor APIs
microphone Media Capture and Streams API
midi Web MIDI API
notifications Notifications API
payment-handler Payment Handler API
persistent-storage Storage API
push Push API
speaker-selection Web Audio Output Devices API
storage-access Storage Access API
window-management Window Management API

不同浏览器支持的权限名称参考如下

类型

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
interface Navigator {
readonly permissions: Permissions
}

partial interface WorkerNavigator {
readonly permissions: Permissions
}

interface Permissions {
query(permissionDesc: PermissionDescriptor): Promise<PermissionStatus>
}

interface PermissionDescriptor {
name: string
}

interface PermissionStatus extends EventTarget {
readonly state: PermissionState
readonly name: string

onchange: ((this: PermissionStatus, ev: Event) => any) | null
}

enum PermissionState {
"granted",
"denied",
"prompt",
}

链接

Beacon API

Beacon API 可用于向服务器发送 HTTP POST 网络请求

通常目的旨在向服务器发送用户数据,特别是在页面关闭时机(能够避免阻碍下一网页的加载)

使用

使用 Navigator 接口的 sendBeacon() 方法发送数据

方法需要传递一个 stringURL,代表请求的目标 URL

方法可以可选地携带一个 ReadableStream Blob ArrayBuffer TypedArray DataView FormData URLSearchParams string,代表请求需要携带的数据

方法返回一个 boolean,表示是否成功完成数据转换

避免使用 beforeunload unload 事件,而是 visibilitychange 事件(或在不兼容时使用 pagehide 事件),因为在移动端网页时卸载事件不能确定地触发

类型

1
2
3
interface Navigator {
sendBeacon(url: string, data?: BodyInit): boolean
}

链接


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