那些你可能不知道的Web APIs

5,778 阅读7分钟

1.Page Visibility(判断网页的可见性)

这个新的 API 的意义在于,通过监听网页的可见性,可以预判网页的卸载,还可以用来节省资源,减缓电能的消耗

我们之前在实现一个业务需求的时候,判断一个页面是否失焦,用的是 onblur、onfocus,有了这个 API,会方便很多。

window.addEventListener('visibilitychange', () => {
  /*if(document.hidden) {
    console.log('Tab呈现之前');
  }
  else {
    console.log('Tab被聚焦');
  }*/
  switch(document.visibilityState) {
    case 'prerender':
      console.log('Tab呈现之前');
      break;
    case 'hidden':
      console.log('Tab隐藏');
      break;
    case 'visible':
      console.log('Tab被聚焦');
      break;
  }
});

使用场景:

  • 聊天室,不可见时能够在浏览器标签头(document.title)中展示消息通知;
  • 切换tab时暂停音频或视频

2.page lifecycle(网页生命周期)

前面,我介绍了 Page Visibility API。有了它,就可以监听各种情况的网页卸载。

但是,它没有解决一个问题。Android、iOS 和最新的 Windows 系统可以随时自主地停止后台进程,及时释放系统资源。也就是说,网页可能随时被系统丢弃掉。Page Visibility API 只在网页对用户不可见时触发,至于网页会不会被系统丢弃掉,它就无能为力了。

为了解决这个问题,W3C 新制定了一个 Page Lifecycle API,统一了网页从诞生到卸载的行为模式,并且定义了新的事件,允许开发者响应网页状态的各种转换。

有了这个 API,开发者就可以预测网页下一步的状态,从而进行各种针对性的处理。Chrome 68 支持这个 API,对于老式浏览器可以使用谷歌开发的兼容库 PageLifecycle.js

生命周期阶段


例子:

window.addEventListener('visibilitychange',() => {
    // visibilitychange事件在网页可见状态发生变化时触发,一般发生在以下几种场景
    switch(document.visibilityState){
        case'prerender': // 网页预渲染 但内容不可见
        case'hidden':    // 内容不可见 处于后台状态,最小化,或者锁屏状态
        case'visible':   // 内容可见
        case'unloaded':  // 文档被卸载
    }
})

使用场景:

  • 聊天室,不可见时能够在浏览器标签头(document.title)中展示消息通知;
  • 切换tab时暂停音频或视频

3.Gamepad(游戏手柄)

Gamepad API 可以给予开发者一种简单、统一的方式来识别并响应游戏控制器(手柄)。其中包含了三个接口、两个事件、一个特殊函数,用来响应控制器的连接与断开、获取其他关于控制器的信息以及识别当前是哪个按键或是哪个控制器被按下了。

接口

  • Gamepad 表示已连接的游戏控制器。
  • GamepadButton 表示已连接手柄上的一个按键。
  • GamepadEvent 表示与控制器相关的事件的事件对象。

连接到游戏手柄

当新游戏手柄连接到计算机时,聚焦页面首先接收gamepadconnected事件。如果在加载页面时已连接游戏手柄,则gamepadconnected当用户按下按钮或移动轴时,将事件分派到聚焦页面:

window.addEventListener("gamepadconnected", function(e) {     
 console.log(e.gamepad.index) // 一个自增的整形数字,对于当前连接到系统的每一个设备是唯一的
 console.log(e.gamepad.id) // 手柄ID 每个游戏手柄都有一个与之关联的唯一ID,可在活动的gamepad属性中找到 
 console.log(e.gamepad.buttons.length) // 一个 gamepadButton 对象的数组,表示设备上的按键的数组
 console.log(e.gamepad.axes.length) // 一个表示控制器设备上存在的坐标轴的数组 (比如控制器摇杆)
});

断开游戏手柄

当游戏手柄断开连接,并且如果页面先前已经接收到该游戏手柄的数据(例如gamepadconnected),则将第二个事件分派到聚焦窗口,gamepaddisconnected

window.addEventListener("gamepaddisconnected", function(e) {
  console.log("Gamepad disconnected from index %d: %s",
    e.gamepad.index, e.gamepad.id);
});

4.Vibration(振动)

振动的API允许开发者直接调用设备震动,使用JavaScript,在给定时间的振动模式

一个单次振动

你可以通过指定单个值或仅由一个值组成的数组来一次振荡振动硬件:

window.navigator.vibrate(200);
window.navigator.vibrate([200]);

振动模式

一组数值描述了设备振动并且不振动的交替时间段。数组中的每个值都将转换成一个整数,然后交替解释为设备应该振动的毫秒数和不振动的毫秒数。例如:

window.navigator.vibrate([200, 100, 200]);

停止振动

当调用window.navigator.vibrate() 的参数为「0」、空白?数组,或?数组全为「0」时,即可取消目前?进行中的振动。

使用场景:移动应用中开发Web游戏或多媒体应用时,可以通过振动来提供感官反馈。

5.device orientation(陀螺仪)

通过绑定事件来获取设备的物理朝向,可以获取到三个数值,分别是:

  • alpha:设备沿着Z轴的旋转角度
  • beta:设备沿着X轴的旋转角度
  • gamma:设备沿着Y轴的旋转角度



代码:

window.addEventListener('deviceorientation',ev => {
    console.log('Beta:',ev.beta); // Z轴的旋转角度
    console.log('Alpha:',ev.Alpha); // X轴的旋转角度
    console.log('Gamma:',ev.gamma); // Y轴的旋转角度
})

6.Clipboard(剪贴板)

Clipboard APIClipboard接口提供了一种读写操作系统剪贴板的方式。

复制:将文本写入剪贴板

writeText() 可以把文本写入剪切板。writeText() 是异步的,它返回一个 Promise

navigator.clipboard.writeText('要复制的文本')
  .then(() => {
    console.log('文本已经成功复制到剪切板');
  })
  .catch(err => {
    // This can happen if the user denies clipboard permissions:
    // 如果用户没有授权,则抛出异常
    console.error('无法复制此文本:', err);
  });

粘贴:从剪贴板中读取文本

navigator.clipboard.readText()
  .then(text => {
    console.log('Pasted content: ', text);
  })
  .catch(err => {
    console.error('Failed to read clipboard contents: ', err);
  });

处理粘贴事件

有计划推出检测剪贴板更改的新事件,但现在最好使用“粘贴”事件。它很适合用于阅读剪贴板文本的新异步方法

document.addEventListener('paste', event => {
  event.preventDefault();
  navigator.clipboard.readText().then(text => {
    console.log('Pasted text: ', text);
  });
});

7.document.execCommand(执行命令)

大多数命令影响documentselection(粗体,斜体等),当其他命令插入新元素(添加链接)或影响整行(缩进)。当使用contentEditable时,调用 execCommand() 将影响当前活动的可编辑元素,使用这个方法来执行一些命令,比如复制,剪切,修改、背景颜色、颜色,缩进,插入图片、选中文字粗体、斜体等

let iframe = document.createElement('ifram');
let doc = iframe.contentDocument;
// 将HTML文档切换成设计模式execCommand

doc.designMode = 'on';

// 然后就可以使用execCommand 这个命令了;
// 执行复制命令

// 全选
doc.execCommand('selectAll')
// 将选中文字变成粗体,同时接下来输入的文字也会成为粗体,
doc.execCommand('bold')
// 将选中文字变成斜体,同时接下来输入的文字也会成为斜体,
doc.execCommand('italic')
// 设置背景颜色,,比如设置背景色为红色,就传入 'red'即可
doc.execCommand('backColor',true,'red')
doc.execCommand('copy')
// 剪切选中区域
doc.execCommand('cut')

简易的富文本编辑器


8.Ambient Light(环境光传感器)

AmbinentLightSensor()构造函数创建一个新AmbientLightSensor对象时,它返回主机装置周围的环境光的光电流电平或照度。

使用

let sensor = new AmbientLightSensor();
sensor.start();
sensor.onchange = (e) => {
  console.log(e.reading.illuminance);
};
sensor.stop();

9.battery status(电池状态)

允许网页从桌面和移动设备访问电池信息。

// 首先去判断当前浏览器是否支持此API
if ('getBattery' in navigator) {
    // 通过这个方法来获取battery对象
    navigator.getBattery().then(battery => {
    // battery 对象包括中含有四个属性
    // charging 是否在充电
    // level   剩余电量
    // chargingTime 充满电所需事件
    // dischargingTime  当前电量可使用时间
    const { charging, level, chargingTime, dischargingTime } = battery;
    // 同时可以给当前battery对象添加事件  对应的分别时充电状态变化 和 电量变化
    battery.onchargingchange = ev => {
        const { currentTarget } = ev;
        const { charging } = currentTarget;
    };
    battery.onlevelchange = ev => {
        const { currentTarget } = ev;
        const { level } = ev;
    }
    })
} else {
    alert('当前浏览器不支持~~~')
}

10.online state(网络状态)

判断网页是否连网。

console.log(navigator.onLine ? 'online' : 'offline');
window.addEventListener('offline', networkStatus);
window.addEventListener('online', networkStatus);

function networkStatus(e) {
  console.log(e.type);
}

11、Web VR

WebVR API 能为虚拟现实设备的渲染提供支持 — 例如像Oculus Rift或者HTC Vive 这样的头戴式设备与 Web apps 的连接。它能让开发者将位置和动作信息转换成3D场景中的运动。基于这项技术能产生很多有趣的应用, 比如虚拟的产品展示,可交互的培训课程,以及超强沉浸感的第一人称游戏

详细介绍请到MDN


参考

阮一峰的Page Visibility API 教程

MDN文档

JS vibrate能让手机振动的API