8個鮮為人知但很實用的Web API
大家好,我是 CUGGZ。
在 Web API 中,有非常有用的對象、屬性和函數(shù)可用于執(zhí)行小到訪問 DOM 這樣的小任務(wù),大到處理音頻、視頻這樣的復(fù)雜任務(wù)。常見的 API 有 Canvas、Web Worker、History、Fetch 等。下面就來看一些不常見但很實用的 Web API。
全文概覽:
Web Audio API
Fullscreen API
Web Speech API
Web Bluetooth API
Vibration API
Broadcast Channel API
Clipboard API
Web Share API
1. Web Audio API
Audio API 允許我們在 Web 上操作音頻流,它可以用于 Web 上的音頻源添加效果和過濾器。音頻源可以來自<audio>、視頻/音頻源文件或音頻網(wǎng)絡(luò)流。
下面來看一個例子:
<body>
<header>
<h2>Web APIs<h2>
</header>
<div class="web-api-cnt">
<div class="web-api-card">
<div class="web-api-card-head">
Demo - Audio
</div>
<div class="web-api-card-body">
<div id="error" class="close"></div>
<div>
<audio controls src="./audio.mp3" id="audio"></audio>
</div>
<div>
<button onclick="audioFromAudioFile.init()">Init</button>
<button onclick="audioFromAudioFile.play()">Play</button>
<button onclick="audioFromAudioFile.pause()">Pause</button>
<button onclick="audioFromAudioFile.stop()">Stop</button>
</div>
<div>
<span>Vol: <input onchange="audioFromAudioFile.changeVolume()" type="range" id="vol" min="1" max="2" step="0.01" value="1" /></span>
<span>Pan: <input onchange="audioFromAudioFile.changePan()" type="range" id="panner" min="-1" max="1" step="0.01" value="0" /></span>
</div>
</div>
</div>
</div>
</body>
<script>
const l = console.log
let audioFromAudioFile = (function() {
var audioContext
var volNode
var pannerNode
var mediaSource
function init() {
l("Init")
try {
audioContext = new AudioContext()
mediaSource = audioContext.createMediaElementSource(audio)
volNode = audioContext.createGain()
volNode.gain.value = 1
pannerNode = new StereoPannerNode(audioContext, { pan:0 })
mediaSource.connect(volNode).connect(pannerNode).connect(audioContext.destination)
}
catch(e) {
error.innerHTML = "此設(shè)備不支持 Web Audio API"
error.classList.remove("close")
}
}
function play() {
audio.play()
}
function pause() {
audio.pause()
}
function stop() {
audio.stop()
}
function changeVolume() {
volNode.gain.value = this.value
l("Vol Range:",this.value)
}
function changePan() {
pannerNode.gain.value = this.value
l("Pan Range:",this.value)
}
return {
init,
play,
pause,
stop,
changePan,
changeVolume
}
})()
</script>
這個例子中將音頻從 <audio> 元素傳輸?shù)?AudioContext,聲音效果(如平移)在被輸出到音頻輸出(揚(yáng)聲器)之前被添加到音頻源。
按鈕 Init 在單擊時調(diào)用 init 函數(shù)。這將創(chuàng)建一個 AudioContext 實例并將其設(shè)置為 audioContext。接下來,它創(chuàng)建一個媒體源 createMediaElementSource(audio),將音頻元素作為音頻源傳遞。音量節(jié)點(diǎn) volNode 由 createGain 創(chuàng)建,可以用來調(diào)節(jié)音量。接下來使用 StereoPannerNode 設(shè)置平移效果,最后將節(jié)點(diǎn)連接至媒體源。
點(diǎn)擊按鈕(Play、Pause、Stop)可以播放、暫停和停止音頻。頁面有一個音量和平移的范圍滑塊,滑動滑塊就可以調(diào)節(jié)音頻的音量和平移效果。
相關(guān)資源:
Demo:https://web-api-examples.github.io/audio.html
MDN 文檔:https://developer.mozilla.org/zh-CN/docs/Web/API/Web_Audio_API
2. Fullscreen API
Fullscreen API 用于在 Web 應(yīng)用程序中開啟全屏模式,使用它就可以在全屏模式下查看頁面/元素。在安卓手機(jī)中,它會溢出瀏覽器窗口和安卓頂部的狀態(tài)欄(顯示網(wǎng)絡(luò)狀態(tài)、電池狀態(tài)等的地方)。
Fullscreen API 方法:
requestFullscreen:系統(tǒng)上以全屏模式顯示所選元素,會關(guān)閉其他應(yīng)用程序以及瀏覽器和系統(tǒng) UI 元素。
exitFullscreen:退出全屏模式并切換到正常模式。
下面來看一個常見的例子,使用全屏模式觀看視頻::
<body>
<header>
<h2>Web APIs<h2>
</header>
<div class="web-api-cnt">
<div class="web-api-card">
<div class="web-api-card-head">
Demo - Fullscreen
</div>
<div class="web-api-card-body">
<div id="error" class="close"></div>
<div>
This API makes fullscreen-mode of our webpage possible. It lets you select the Element you want to view in fullscreen-mode, then it shuts off the browsers window features like URL bar, the window pane, and presents the Element to take the entire width and height of the system.
In Android phones, it will remove the browsers window and the Android UI where the network status, battery status are displayed, and display the Element in full width of the Android system.
</div>
<div class="video-stage">
<video id="video" src="./video.mp4"></video>
<button onclick="toggle()">Toogle Fullscreen</button>
</div>
<div>
This API makes fullscreen-mode of our webpage possible. It lets you select the Element you want to view in fullscreen-mode, then it shuts off the browsers window features like URL bar, the window pane, and presents the Element to take the entire width and height of the system.
In Android phones, it will remove the browsers window and the Android UI where the network status, battery status are displayed, and display the Element in full width of the Android system.
</div>
</div>
</div>
</div>
</body>
<script>
const l =console.log
function toggle() {
const videoStageEl = document.querySelector(".video-stage")
if(videoStageEl.requestFullscreen) {
if(!document.fullscreenElement){
videoStageEl.requestFullscreen()
}
else {
document.exitFullscreen()
}
} else {
error.innerHTML = "此設(shè)備不支持 Fullscreen API"
error.classList.remove("close")
}
}
</script>
可以看到,video 元素在 div#video-stage 元素中,帶有一個按鈕 Toggle Fullscreen:
當(dāng)點(diǎn)擊按鈕切換全屏?xí)r,我們想讓元素 div#video-stage 全屏顯示。toggle 函數(shù)的實現(xiàn)如下:
function toggle() {
const videoStageEl = document.querySelector(".video-stage")
if(!document.fullscreenElement)
videoStageEl.requestFullscreen()
else
document.exitFullscreen()
}
這里通過 querySelector 查找 div#video-stage 元素并將其 HTMLDivElement 實例保存在 videoStageEl 上。
然后,使用 document.fullsreenElement 屬性來確定 document 是否是全屏的,所以可以在 videoStageEl 上調(diào)用 requestFullscreen()。這將使 div#video-stage 占據(jù)整個設(shè)備的視圖。
如果在全屏模式下點(diǎn)擊 Toggle Fullscreen 按鈕,就會在 document 上調(diào)用 exitFullcreen,這樣 UI 視圖就會返回到普通視圖(退出全屏)。
相關(guān)資源:
Demo:https://web-api-examples.github.io/fullscreen.html
MDN 文檔:https://developer.mozilla.org/zh-CN/docs/Web/API/Fullscreen_API
3. Web Speech API
Web Speech API 提供了將語音合成和語音識別添加到 Web 應(yīng)用程序的功能。使用此 API,我們將能夠向 Web 應(yīng)用程序發(fā)出語音命令,就像在 Android 上通過其 Google Speech 或在 Windows 中使用 Cortana 一樣。
下面來看一個簡單的例子,使用 Web Speech API 實現(xiàn)文字轉(zhuǎn)語音和語音轉(zhuǎn)文字:
<body>
<header>
<h2>Web APIs<h2>
</header>
<div class="web-api-cnt">
<div id="error" class="close"></div>
<div class="web-api-card">
<div class="web-api-card-head">
Demo - Text to Speech
</div>
<div class="web-api-card-body">
<div>
<input placeholder="Enter text here" type="text" id="textToSpeech" />
</div>
<div>
<button onclick="speak()">Tap to Speak</button>
</div>
</div>
</div>
<div class="web-api-card">
<div class="web-api-card-head">
Demo - Speech to Text
</div>
<div class="web-api-card-body">
<div>
<textarea placeholder="Text will appear here when you start speeaking." id="speechToText"></textarea>
</div>
<div>
<button onclick="tapToSpeak()">Tap and Speak into Mic</button>
</div>
</div>
</div>
</div>
</body>
<script>
try {
var speech = new SpeechSynthesisUtterance()
var SpeechRecognition = SpeechRecognition;
var recognition = new SpeechRecognition()
} catch(e) {
error.innerHTML = "此設(shè)備不支持 Web Speech API"
error.classList.remove("close")
}
function speak() {
speech.text = textToSpeech.value
speech.volume = 1
speech.rate=1
speech.pitch=1
window.speechSynthesis.speak(speech)
}
function tapToSpeak() {
recognition.onstart = function() { }
recognition.onresult = function(event) {
const curr = event.resultIndex
const transcript = event.results[curr][0].transcript
speechToText.value = transcript
}
recognition.onerror = function(ev) {
console.error(ev)
}
recognition.start()
}
</script>
第一個演示 Demo - Text to Speech 演示了使用這個 API 和一個簡單的輸入字段,接收輸入文本和一個按鈕來執(zhí)行語音操作。
function speak() {
const speech = new SpeechSynthesisUtterance()
speech.text = textToSpeech.value
speech.volume = 1
speech.rate = 1
speech.pitch = 1
window.speechSynthesis.speak(speech)
}
它實例化了 SpeechSynthesisUtterance() 對象,將文本設(shè)置為從輸入框中輸入的文本中朗讀。然后,使用 speech 對象調(diào)用 SpeechSynthesis#speak 函數(shù),在揚(yáng)聲器中說出輸入框中的文本。
第二個演示 Demo - Speech to Text 將語音識別為文字。點(diǎn)擊 Tap and Speak into Mic 按鈕并對著麥克風(fēng)說話,我們說的話會被翻譯成文本輸入框中的內(nèi)容。
點(diǎn)擊 Tap and Speak into Mic 按鈕會調(diào)用 tapToSpeak 函數(shù):
function tapToSpeak() {
var SpeechRecognition = SpeechRecognition;
const recognition = new SpeechRecognition()
recognition.onstart = function() { }
recognition.onresult = function(event) {
const curr = event.resultIndex
const transcript = event.results[curr][0].transcript
speechToText.value = transcript
}
recognition.onerror = function(ev) {
console.error(ev)
}
recognition.start()
}
這里實例化了 SpeechRecognition,然后注冊事件處理程序和回調(diào)。語音識別開始時調(diào)用 onstart,發(fā)生錯誤時調(diào)用 onerror。每當(dāng)語音識別捕獲一條線時,就會調(diào)用 onresult。
在 onresult 回調(diào)中,提取內(nèi)容并將它們設(shè)置到 textarea 中。因此,當(dāng)我們對著麥克風(fēng)說話時,文字會出現(xiàn)在 textarea 內(nèi)容中。
相關(guān)資源:
Demo:https://web-api-examples.github.io/speech.html
MDN 文檔:https://developer.mozilla.org/zh-CN/docs/Web/API/Web_Speech_API
4. Web Bluetooth API
Bluetooth API 讓我們可以訪問手機(jī)上的低功耗藍(lán)牙設(shè)備,并使用它將網(wǎng)頁上的數(shù)據(jù)共享到另一臺設(shè)備。
基本 API 是 navigator.bluetooth.requestDevice。調(diào)用它將使瀏覽器提示用戶使用設(shè)備選擇器,用戶可以在其中選擇一個設(shè)備或取消請求。navigator.bluetooth.requestDevice 需要一個強(qiáng)制對象。此對象定義過濾器,用于返回與過濾器匹配的藍(lán)牙設(shè)備。
下面來看一個簡單的例子,使用 navigator.bluetooth.requestDevice API 從 BLE 設(shè)備檢索基本設(shè)備信息:
<body>
<header>
<h2>Web APIs<h2>
</header>
<div class="web-api-cnt">
<div class="web-api-card">
<div class="web-api-card-head">
Demo - Bluetooth
</div>
<div class="web-api-card-body">
<div id="error" class="close"></div>
<div>
<div>Device Name: <span id="dname"></span></div>
<div>Device ID: <span id="did"></span></div>
<div>Device Connected: <span id="dconnected"></span></div>
</div>
<div>
<button onclick="bluetoothAction()">Get BLE Device</button>
</div>
</div>
</div>
</div>
</body>
<script>
function bluetoothAction(){
if(navigator.bluetooth) {
navigator.bluetooth.requestDevice({
acceptAllDevices: true
}).then(device => {
dname.innerHTML = device.name
did.innerHTML = device.id
dconnected.innerHTML = device.connected
}).catch(err => {
error.innerHTML = "Oh my!! Something went wrong."
error.classList.remove("close")
})
} else {
error.innerHTML = "Bluetooth is not supported."
error.classList.remove("close")
}
}
</script>
這里會顯示設(shè)備信息。單擊 Get BLE Device 按鈕會調(diào)用 bluetoothAction 函數(shù):
function bluetoothAction(){
navigator.bluetooth.requestDevice({
acceptAllDevices: true
}).then(device => {
dname.innerHTML = device.name
did.innerHTML = device.id
dconnected.innerHTML = device.connected
}).catch(err => {
console.error("Oh my!! Something went wrong.")
})
}
bluetoothAction 函數(shù)調(diào)用帶有 acceptAllDevices:true 選項的 navigator.bluetooth.requestDevice API,這將使其掃描并列出所有附近的藍(lán)牙活動設(shè)備。它返回了一個 promise,所以將它解析為從回調(diào)函數(shù)中獲取一個參數(shù) device,這個 device 參數(shù)將保存列出的藍(lán)牙設(shè)備的信息。這是我們使用其屬性在設(shè)備上顯示信息的地方。
相關(guān)資源:
Demo:https://web-api-examples.github.io/bluetooth.html
MDN 文檔:https://developer.mozilla.org/en-US/docs/Web/API/Web_Bluetooth_API
5. Vibration API
Vibration API 可以使我們的設(shè)備振動,作為對我們應(yīng)該響應(yīng)的新數(shù)據(jù)或信息的通知或物理反饋的一種方式。
執(zhí)行振動的方法是 navigator.vibrate(pattern)。pattern 是描述振動模式的單個數(shù)字或數(shù)字?jǐn)?shù)組。
這將使設(shè)備振動在 200 毫秒之后停止:
navigator.vibrate(200)
navigator.vibrate([200])
這將使設(shè)備先振動 200 毫秒,再暫停 300 毫秒,最后振動 400 毫秒并停止:
navigator.vibrate([200, 300, 400])
可以通過傳遞 0、[]、[0,0,0] 來消除振動。
下面來看一個簡單的例子:
<body>
<header>
<h2>Web APIs<h2>
</header>
<div class="web-api-cnt">
<div class="web-api-card">
<div class="web-api-card-head">
Demo - Vibration
</div>
<div class="web-api-card-body">
<div id="error" class="close"></div>
<div>
<input id="vibTime" type="number" placeholder="Vibration time" />
</div>
<div>
<button onclick="vibrate()">Vibrate</button>
</div>
</div>
</div>
</div>
</body>
<script>
if(navigator.vibrate) {
function vibrate() {
const time = vibTime.value
if(time != "")
navigator.vibrate(time)
}
} else {
error.innerHTML = "Vibrate API not supported in this device."
error.classList.remove("close")
}
</script>
這里有一個輸入框和一個按鈕。在輸入框中輸入振動的持續(xù)時間并按下按鈕。我們的設(shè)備將在輸入的時間內(nèi)振動。
相關(guān)資源:
Demo:https://web-api-examples.github.io/vibration.html
MDN 文檔:https://developer.mozilla.org/zh-CN/docs/Web/API/Vibration_API
6. Broadcast Channel API
Broadcast Channel API 允許從同源的不同瀏覽上下文進(jìn)行消息或數(shù)據(jù)的通信。其中,瀏覽上下文指的是窗口、選項卡、iframe、worker 等。
BroadcastChannel 類用于創(chuàng)建或加入頻道:
const politicsChannel = new BroadcastChannel("politics")
politics 是頻道的名稱,任何使用 politics 始化 BroadcastChannel 構(gòu)造函數(shù)的上下文都將加入 politics 頻道,它將接收在頻道上發(fā)送的任何消息,并可以將消息發(fā)送到頻道中。
如果它是第一個具有 politics 的 BroadcastChannel 構(gòu)造函數(shù),則將創(chuàng)建該頻道??梢允褂?BroadcastChannel.postMessage API 來將消息發(fā)布到頻道。使用 BroadcastChannel.onmessage API 要訂閱頻道消息。
下面來看一個簡單的聊天應(yīng)用:
<body>
<header>
<h2>Web APIs<h2>
</header>
<div class="web-api-cnt">
<div class="web-api-card">
<div class="web-api-card-head">
Demo - BroadcastChannel
</div>
<div class="web-api-card-body">
<div class="page-info">Open this page in another <i>tab</i>, <i>window</i> or <i>iframe</i> to chat with them.</div>
<div id="error" class="close"></div>
<div id="displayMsg" style="font-size:19px;text-align:left;">
</div>
<div class="chatArea">
<input id="input" type="text" placeholder="Type your message" />
<button onclick="sendMsg()">Send Msg to Channel</button>
</div>
</div>
</div>
</div>
</body>
<script>
const l = console.log;
try {
var politicsChannel = new BroadcastChannel("politics")
politicsChannel.onmessage = onMessage
var userId = Date.now()
} catch(e) {
error.innerHTML = "BroadcastChannel API not supported in this device."
error.classList.remove("close")
}
input.addEventListener("keydown", (e) => {
if(e.keyCode === 13 && e.target.value.trim().length > 0) {
sendMsg()
}
})
function onMessage(e) {
const {msg,id}=e.data
const newHTML = "<div class='chat-msg'><span><i>"+id+"</i>: "+msg+"</span></div>"
displayMsg.innerHTML = displayMsg.innerHTML + newHTML
displayMsg.scrollTop = displayMsg.scrollHeight
}
function sendMsg() {
politicsChannel.postMessage({msg:input.value,id:userId})
const newHTML = "<div class='chat-msg'><span><i>Me</i>: "+input.value+"</span></div>"
displayMsg.innerHTML = displayMsg.innerHTML + newHTML
input.value = ""
displayMsg.scrollTop = displayMsg.scrollHeight
}
</script>
這里有一個簡單的文本和按鈕。輸入消息,然后按按鈕發(fā)送消息。下面初始化了politicalChannel,并在 politicalChannel 上設(shè)置了一個 onmessage 事件監(jiān)聽器,這樣它就可以接收和顯示消息。
點(diǎn)擊按鈕就會調(diào)用sendMsg 函數(shù)。它通過 BroadcastChannel#postMessage API 將消息發(fā)送到 politics 頻道。任何初始化此腳本的選項卡、iframe 或工作程序都將接收從此處發(fā)送的消息,因此此頁面將接收從其他上下文發(fā)送的消息。相關(guān)資源:
Demo:https://web-api-examples.github.io/broadcastchannel.html
MDN 文檔:https://developer.mozilla.org/zh-CN/docs/Web/API/Broadcast_Channel_API
7. Clipboard API
復(fù)制、剪切和粘貼等剪貼板操作是應(yīng)用程序中最常見的一些功能。Clipboard API 使 Web 用戶能夠訪問系統(tǒng)剪貼板并執(zhí)行基本的剪貼板操作。
以前,可以使用 document.execCommand 與系統(tǒng)剪貼板進(jìn)行交互?,F(xiàn)代異步剪貼板 API 提供了直接讀取和寫入剪貼板內(nèi)容的訪問權(quán)限。
從剪貼板讀取內(nèi)容:
navigator.clipboard.readText().then(clipText =>
document.getElementById("outbox").innerText = clipText
);
將內(nèi)容寫入剪貼板:
function updateClipboard(newClip) {
navigator.clipboard.writeText(newClip).then(function() {
/* clipboard successfully set */
}, function() {
/* clipboard write failed */
});
}
相關(guān)資源:
MDN 文檔:https://developer.mozilla.org/zh-CN/docs/Web/API/Clipboard_API
8. Web Share API
Share API 可幫助我們在 web 應(yīng)用上實現(xiàn)共享功能。它給人以移動原生共享的感覺。它使共享文本、文件和指向設(shè)備上其他應(yīng)用程序的鏈接成為可能。
可通過 navigator.share 方法訪問 Web Share API:
if (navigator.share) {
navigator.share({
title: '百度',
text: '百度一下',
url: '<https://www.baidu.com/>',
})
.then(() => console.log('分享成功'))
.catch((error) => console.log('分享失敗', error));
}
上面的代碼使用原生 JavaScript 實現(xiàn)了文本共享。需要注意,我們只能使用 onclick 事件調(diào)用此操作:
function Share({ label, text, title }) {
const shareDetails = { title, text };
const handleSharing = async () => {
if (navigator.share) {
try {
await navigator.share(shareDetails).then(() => console.log("Sent"));
} catch (error) {
console.log(`Oops! I couldn't share to the world because: ${error}`);
}
} else {
// fallback code
console.log(
"Web share is currently not supported on this browser. Please provide a callback"
);
}
};
return (
<button onClick={handleSharing}>
<span>{label}</span>
</button>
);
}
相關(guān)資源:
MDN 文檔:https://developer.mozilla.org/en-US/docs/Web/API/Web_Share_API
參考:
https://blog.bitsrc.io/10-useful-web-apis-for-2020-8e43905cbdc5
https://blog.logrocket.com/5-web-apis-mobile-functionality/
作者:GUOZE
歡迎關(guān)注微信公眾號 :前端充電寶