在 2019年穀歌開發者大會 —— 實現適用於Web新功能 的半小時演講中,Thomas Steiner介紹了一些Chrome已經發布和即將支持的新API。這些新增的API使得web app可以實現一些native app的功能,並同時堅持保護用戶的安全性、隱私、信任及其餘 web 核心原則。前端
Through our capabilities project, we want to make it possible for web apps to do anything native apps can, by exposing the capabilities of native platforms to the web platform, while maintaining user security, privacy, trust, and other core tenets of the web. (developers.google.com/web/updates…)git
注:這些 API 有三種狀態:github
狀態:Chrome 76 發佈web
做用:支持對於圖片的複製粘貼json
首先得到 Blob
對象格式的圖片,而後將 ClipboardItem
這個對象做爲數組項傳入新的異步方法 navigator.clipboard.write()
中。目前只支持一次傳遞一張圖片,將來會支持多張圖片。api
try {
const imgURL = 'https://developers.google.com/web/updates/images/generic/file.png';
const data = await fetch(imgURL);
const blob = await data.blob();
await navigator.clipboard.write([
new ClipboardItem(Object.defineProperty({}, blob.type, {
value: blob,
enumerable: true
}))
]);
console.log('Image copied.');
} catch(e) {
console.error(e, e.message);
}
複製代碼
經過 navigator.clipboard.read()
方法可得到一個由 clipboardItem
組成的數組。因爲這些方法都是異步的,此處建議建議用 for ... of
循環 image 數組。數組
async function getClipboardContents() {
try {
const clipboardItems = await navigator.clipboard.read();
for (const clipboardItem of clipboardItems) {
try {
for (const type of clipboardItem.types) {
const blob = await clipboardItem.getType(type);
console.log(URL.createObjectURL(blob));
}
} catch (e) {
console.error(e, e.message);
}
}
} catch (e) {
console.error(e, e.message);
}
}
複製代碼
能夠經過監聽 paste
事件自定義粘貼動做。注意要先preventDefault()
。瀏覽器
document.addEventListener('paste', async (e) => {
e.preventDefault();
getClipboardContents();
});
複製代碼
一樣的,經過監聽 copy
事件能夠自定義粘貼動做,此事件包含一個 clipboardData
的屬性,能夠從中獲取剪貼板中的數據。安全
document.addEventListener('copy', async (e) => {
e.preventDefault();
try {
for (const item of e.clipboardData.items) {
await navigator.clipboard.write([
new ClipboardItem(Object.defineProperty({}, item.type, {
value: item,
enumerable: true
}))
]);
}
console.log('Image copied.');
} catch(e) {
console.error(e, e.message);
}
});
複製代碼
狀態:Available as an origin trial for Androidapp
做用:使用戶能夠在 web app 中打開通信錄,分享指定的內容給選中的聯繫人
一個使 web app 更接近於 native app 的 API。經過 navigator.contacts.select()
這個異步方法打開通信錄列表,此方法包含兩個參數:props
,提早設定好的想要返回的屬性數組;option
,是否能夠選擇多個聯繫人的對象。
const props = ['name', 'email', 'tel'];
const opts = {multiple: true};
try {
const contacts = await navigator.contacts.select(props, opts);
handleResults(contacts);
} catch (ex) {
// Handle any errors here.
}
複製代碼
此 API 的返回值爲一個由聯繫人屬性對象組成的數組。
[{
"email": [],
"name": ["Queen O'Hearts"],
"tel": ["+1-206-555-1000", "+1-206-555-1111"]
}]
複製代碼
狀態:Available as an origin trial
做用:在 web app 的圖標上顯示消息提醒
相比於發送推送通知,在 PWA 的圖標上靜默顯示通知是更接近於原生應用的體驗。儘管如此,Chrome 仍然建議不要根據 web app 的安裝狀態調用此 API,由於Badgin API 能夠應用於任何瀏覽器但願顯示標記的地方,因此不須要預設此 API 的做用條件。若是環境不支持,標記就不會顯示。
設置/清除標記能夠經過 window.ExperimentalBadge
對象,它有兩個方法 set([number])
和 clear()
分別用於設置指定數目的標記,和清除標記。
// In a web page
const unreadCount = 24;
window.ExperimentalBadge.set(unreadCount);
複製代碼
狀態:Launched
做用:使 web app 能夠向其餘 app 分享文件
仍然是一個改善 PWA 用戶體驗使其更接近於原生應用的 API。經過 navigator.canShare()
方法判斷分享的文件是否能夠分享以及獲取分享數據。
目前支持分享的文件爲 Image, video, audio 以及文本文件,將來會提供更多類型文件的支持。
if (navigator.canShare && navigator.canShare( { files: filesArray } )) {
navigator.share({
files: filesArray,
title: 'Vacation Pictures',
text: 'Barb\nHere are the pictures from our vacation.\n\nJoe',
})
.then(() => console.log('Share was successful.'))
.catch((error) => console.log('Sharing failed', error));
} else {
console.log('Your system doesn\'t support sharing files.');
}
複製代碼
此外能夠經過 Web Share Target API 將你的 PWA 註冊爲能夠被分享的目標,之前只有原生應用才能夠被分享。註冊方式爲在你的 manifest.json
中添加一個 share_traget
對象,
"share_target": {
"action": "/share-target/",
"method": "GET",
"enctype": "application/x-www-form-urlencoded",
"params": {
"title": "title",
"text": "text",
"url": "url"
}
}
複製代碼
其中的 params
能夠自定義爲你已有的 share URL scheme,method
默認爲 GET
,也可將它設爲 POST
。
當你的 web app 被指定分享某個文件而且 method
是 GET
時,瀏覽器會在 action
指定的 URL 中打開一個新窗口,並帶上 params
中指定的一系列參數。
window.addEventListener('DOMContentLoaded', () => {
const parsedUrl = new URL(window.location);
// searchParams.get() will properly handle decoding the values.
console.log('Title shared: ' + parsedUrl.searchParams.get('title'));
console.log('Text shared: ' + parsedUrl.searchParams.get('text'));
console.log('URL shared: ' + parsedUrl.searchParams.get('url'));
});
複製代碼
狀態:Behind a flag
做用:PWA 能夠讀寫本地文件系統了!
仍然是一個使 PWA 更像原生應用的 API。用戶授予權限後,web app 經過此 API 能夠即時讀寫用戶設備上的本地文件,方法爲 window.chooseFileSystemEntries()
。默認只可選取一個文件,能夠經過設置參數使其選取多個文件。
let fileHandle;
butOpenFile.addEventListener('click', async (e) => {
fileHandle = await window.chooseFileSystemEntries();
// Do something with the file handle
});
複製代碼
fileHandle
爲調用此 API 的回調,它包含各類和文件互動的屬性和方法。好比讀取文件。
const file = await fileHandle.getFile();
const contents = await file.text();
複製代碼
須要建立文件時,向 window.chooseFileSystemEntries()
中傳入一個配置參數便可。
function getNewFileHandle() {
const opts = {
type: 'saveFile',
accepts: [{
description: 'Text file',
extensions: ['txt'],
mimeTypes: ['text/plain'],
}],
};
const handle = window.chooseFileSystemEntries(opts);
return handle;
}
複製代碼
打開文件目錄枚舉文件的寫法爲,在此 API 中傳入一個 openDirectory
參數。
const butDir = document.getElementById('butDirectory');
butDir.addEventListener('click', async (e) => {
const opts = {type: 'openDirectory'};
const handle = await window.chooseFileSystemEntries(opts);
const entries = await handle.getEntries();
for await (const entry of entries) {
const kind = entry.isFile ? 'File' : 'Directory';
console.log(kind, entry.name);
}
});
複製代碼
Google 團隊在致力於彌合 PWA 和原生應用之間的間隙,力圖拓展 web app 的邊界使其儘量地提供原生應用的用戶體驗,例如他們還新提出了 Barcode Detection API(識別二維碼),短信/本地通知 push 等試驗性功能。由此,在移動端開發各個框架的 PK 及大前端浩蕩的潮流中, PWA 能夠利用其支持全部平臺,日益完善的 web api 以及較少開發成本等優點在輕量應用的開發中佔據更重要的位置。
P.S 上述 API 主要參考自 Goole developer 官網 ,若是有理解錯誤的地方麻煩評論告訴我啊
P.P.S 此次大會聽過以後以爲 Flutter 很好用的樣子!