在Web API 中,有非常有用的物件、屬性和函數可用於執行小到存取DOM 這樣的小任務,大到處理音訊、視訊這樣的複雜任務。常見的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
Audio API 允許我們在Web 上操作音訊串流,它可以用於Web 上的音訊來源添加效果和過濾器。音訊來源可以來自<audio>
、視訊/音訊來源檔案或音訊網路串流。
下面來看一個例子:
<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 = "此裝置不支援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>
元素傳輸到AudioContext
,聲音效果(如平移)在被輸出到音訊輸出(揚聲器)之前被加入到音訊來源。
按鈕Init 在單擊時調用init
函數。 這將建立一個AudioContext
實例並將其設定為audioContext
。 接下來,它會建立一個媒體來源createMediaElementSource(audio)
,將音訊元素作為音訊來源傳遞。音量節點volNode
由createGain
創建,可以用來調整音量。接下來使用StereoPannerNode
設定平移效果,最後將節點連接至媒體來源。
點擊按鈕(Play、Pause、Stop)可以播放、暫停和停止音訊。頁面有一個音量和平移的範圍滑桿,滑動滑桿就可以調整音訊的音量和平移效果。
相關資源:
Fullscreen API 用於在Web 應用程式中開啟全螢幕模式,使用它就可以在全螢幕模式下查看頁面/元素。在安卓手機中,它會溢出瀏覽器視窗和安卓頂部的狀態列(顯示網路狀態、電池狀態等的地方)。
Fullscreen API 方法:
requestFullscreen
:系統上以全螢幕模式顯示所選元素,會關閉其他應用程式以及瀏覽器和系統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 presenws the Elementire 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 presenws the Elementire 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 = "此裝置不支援Fullscreen API" error.classList.remove("close") } } </script>
可以看到,video 元素在div#video-stage 元素中,帶有一個按鈕Toggle Fullscreen。
當點擊按鈕切換全螢幕時,我們想要讓元素div#video-stage
全螢幕顯示。 toggle
函數的實作如下:
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
上呼叫requestFullscreen()
。 這將使div#video-stage
佔據整個裝置的視圖。
如果在全螢幕模式下點選Toggle Fullscreen 按鈕,就會在document
上呼叫exitFullcreen
,這樣UI 視圖就會回到普通視圖(退出全螢幕)。
相關資源:
Web Speech API 提供了將語音合成和語音識別新增到Web 應用程式的功能。使用此API,我們將能夠向Web 應用程式發出語音命令,就像在Android 上透過其Google Speech 或在Windows 中使用Cortana 一樣。
下面來看一個簡單的例子,使用Web Speech API 實現文字轉語音和語音轉文字:
<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 = "此設備不支援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 和一個簡單的輸入字段,接收輸入文字和一個按鈕來執行語音操作。
function speak() { const speech = new SpeechSynthesisUtterance() speech.text = textToSpeech.value speech.volume = 1 speech.rate = 1 speech.pitch = 1 window.speechSynthesis.speak(speech) }
它實例化了SpeechSynthesisUtterance()
對象,將文字設定為從輸入框輸入的文字中朗讀。 然後,使用speech
物件呼叫SpeechSynthesis#speak
函數,在揚聲器中說出輸入框中的文字。
第二個示範Demo - Speech to Text 將語音辨識為文字。 點擊Tap and Speak into Mic 按鈕並對麥克風說話,我們說的話會被翻譯成文字輸入框中的內容。
點選Tap and Speak into Mic 按鈕會呼叫tapToSpeak 函數:
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
,然後註冊事件處理程序和回呼。語音辨識開始時呼叫onstart
,發生錯誤時呼叫onerror
。 每當語音辨識捕獲一條線時,就會呼叫onresult
。
在onresult
回呼中,提取內容並將它們設定到textarea
中。 因此,當我們對著麥克風說話時,文字會出現在textarea
內容中。
相關資源:
Bluetooth API 讓我們可以存取手機上的低功耗藍牙設備,並使用它將網頁上的資料共享到另一台設備。
基本API 是navigator.bluetooth.requestDevice
。 呼叫它將使瀏覽器提示用戶使用設備選擇器,用戶可以在其中選擇一個設備或取消請求。 navigator.bluetooth.requestDevice
需要一個強制物件。 此物件定義過濾器,用於傳回與過濾器相符的藍牙裝置。
下面來看一個簡單的例子,使用navigator.bluetooth.requestDevice
API 從BLE 裝置擷取基本裝置資訊:
<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>
這裡會顯示設備資訊。 點選Get BLE Device 按鈕會呼叫bluetoothAction
函數:
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
函數呼叫帶有acceptAllDevices:true
選項的navigator.bluetooth.requestDevice
API,這將使其掃描並列出所有附近的藍牙活動裝置。 它傳回了一個promise
,所以將它解析為從回調函數中取得一個參數device,這個device 參數將保存列出的藍牙裝置的資訊。這是我們使用其屬性在設備上顯示資訊的地方。
相關資源:
Vibration API 可以讓我們的裝置振動,作為對我們應該回應的新數據或資訊的通知或物理回饋的一種方式。
執行振動的方法是navigator.vibrate(pattern)
。 pattern
是描述振動模式的單一數字或數字陣列。
這將使設備振動在200 毫秒之後停止:
navigator.vibrate(200) navigator.vibrate([200])
這將使設備先振動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>
這裡有一個輸入框和一個按鈕。 在輸入框中輸入振動的持續時間並按下按鈕。我們的設備將在輸入的時間內振動。
相關資源:
Broadcast Channel API 允許從同源的不同瀏覽上下文進行訊息或資料的通訊。其中,瀏覽上下文指的是視窗、選項卡、iframe、worker 等。
BroadcastChannel
類別用於建立或加入頻道:
const politicsChannel = new BroadcastChannel("politics")
politics
是頻道的名稱,任何使用politics
啟動BroadcastChannel
建構子的上下文都會加入politics
頻道,它將接收在頻道上發送的任何訊息,並可以將訊息發送到頻道中。
如果它是第一個具有politics
的BroadcastChannel
建構函數,則會建立該頻道。可以使用BroadcastChannel.postMessage API
來將訊息發佈到頻道。使用BroadcastChannel.onmessage
API 要訂閱頻道訊息。
下面來看一個簡單的聊天應用程式:
<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> 或 <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>
這裡有一個簡單的文字和按鈕。 輸入訊息,然後按按鈕發送訊息。下面初始化了politicalChannel
,並在politicalChannel
上設定了onmessage
事件監聽器,這樣它就可以接收和顯示訊息。
點擊按鈕就會呼叫sendMsg
函數。 它透過BroadcastChannel#postMessage
API 將訊息傳送到politics
頻道。任何初始化此腳本的標籤、iframe 或工作程序都會接收從此處發送的訊息,因此此頁面將接收從其他上下文發送的訊息。相關資源:
複製、剪下和貼上等剪貼簿操作是應用程式中最常見的一些功能。 Clipboard API 使Web 使用者能夠存取系統剪貼簿並執行基本的剪貼簿操作。
以前,可以使用document.execCommand
與系統剪貼簿進行互動。 現代非同步剪貼簿API 提供了直接讀取和寫入剪貼簿內容的存取權限。
從剪貼簿讀取內容:
navigator.clipboard.readText().then(clipText => document.getElementById("outbox").innerText = clipText );
將內容寫入剪貼簿:
function updateClipboard(newClip) { navigator.clipboard.writeText(newClip).then(function() { /* clipboard successfully 設定 */ }, function() { /* clipboard write failed */ }); }
相關資源:
Share API 可協助我們在web 應用上實現共享功能。它給人以行動原生共享的感覺。它使共享文字、文件和指向設備上其他應用程式的連結成為可能。
可透過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 實作了文字共享。需要注意,我們只能使用onclick
事件呼叫此操作:
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> ); }
相關資源: