原來我對好多 Web API
一無所知,打開了我新世界的大門,將來 Web
能夠作到更多,早日一統江湖吧,吼吼吼。javascript
雖然這些 API
不少目前還存在兼容性的問題,可是仍是有必要了解一下的,文中的代碼,我已經都測試過了。但願你看完以後可以有所收穫。css
原文連接:blog.bitsrc.io/10-useful-w…html
你可能已經知道並使用更爲流行的 Web APIs
(Web Worker
,Fetch
等),但也有少數不那麼流行的 API
,我我的喜歡使用,並建議你也嘗試一下。java
這篇文章中描述的全部 Web API
示例均可以在這裏找到:git
Web Audio API MDNgithub
Web Audio API
容許你在 Web
上操做音頻流。它可用於向網絡上的音頻源添加效果和濾鏡。web
音頻源能夠來自 <audio>
,視頻/音頻源文件或音頻網絡流。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 - Audio </div>
<div class="web-api-card-body">
<div id="error" class="close"></div>
<div>
<audio controls src="./lovely.mp4" 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="3" 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) console.log(volNode) } catch (e) { error.innerHTML = "The Web Audio API is not supported in this device." error.classList.remove("close") } } function play() { audio.play() } function pause() { audio.pause() } function stop() { audio.stop() } function changeVolume() { volNode.gain.value = document.getElementById('vol').value } function changePan() { pannerNode.gain.value = tdocument.getElementById('panner').value } return { init, play, pause, stop, changePan, changeVolume } })() </script>
複製代碼
譯者注:源代碼有點小問題,上面的代碼我已經修改過,能夠運行,不過mp4文件換成本身本地有的。瀏覽器
此示例將音頻從 <audio>
元素傳遞到 AudioContext
。聲音效果(例如聲像)在添加到音頻輸出(揚聲器)以前已添加到音頻源。
單擊 Init
按鈕將調用 init
函數。這將建立一個 AudioContext
實例並將其設置爲 audioContext
。接下來,它建立一個媒體源 createMediaElementSource(audio)
,將音頻元素做爲音頻源傳遞。
createGain
建立音量節點 volNode
。在這裏,咱們調整音頻的音量。接下來,使用 StereoPannerNode
設置聲像效果。最後,將節點鏈接到媒體源。
咱們有一個音量和聲像的滑塊,拖動它們會影響音量和音頻的聲像效果。
這個例子有問題,因此該連接也沒法正常使用,能夠拷貝上面的代碼在本地運行
Fullscreen API
讓咱們可以在 Web app
中啓用全屏模式。它使你能夠選擇要在全屏模式下查看的元素。在 Android
手機中,它將刪除瀏覽器窗口和 Android
頂部狀態欄(顯示網絡狀態,電池狀態等的地方)。
方法:
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 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="./lovely.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") console.log(videoStageEl.requestFullscreen) if (videoStageEl.requestFullscreen) { if (!document.fullscreenElement) { videoStageEl.requestFullscreen() } else { document.exitFullscreen() } } else { error.innerHTML = "Fullscreen API not supported in this device." error.classList.remove("close") } } </script>
複製代碼
video
元素在 div#video-stage
元素中,並帶有一個按鈕 Toggle Fullscreen
。
當咱們單擊 Toggle Fullscreen
按鈕時,咱們但願使元素 div#video-stage
變爲全屏顯示。
看一下 toggle
這個函數:
function toggle() {
const videoStageEl = document.querySelector(".video-stage")
if(!document.fullscreenElement)
videoStageEl.requestFullscreen()
else
document.exitFullscreen()
}
複製代碼
獲取 div#video-stage
元素,並將其實例保留在 videoStageEl
上。
咱們用過 document.fullsreenElement
屬性能夠知道該元素是否處於全屏模式,若是不是全屏模式,能夠調用 videoStageEl
上的 requestFullscreen()
方法,使 div#video-stage
接管整個設備視圖。
若是在全屏模式下點擊 Toggle Fullscreen
按鈕,將會調用 document.exitFullcreen()
,從而返回到普通視圖。
注:該連接中的視頻資源找不到了,可是全屏功能是正常的,你們也能夠在本地測試
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 recognition = new SpeechRecognition() } catch (e) { error.innerHTML = "Web Speech API not supported in this device." error.classList.remove("close") } function speak() { speech.text = textToSpeech.value speech.volume = 1 speech.rate = 1 speech.pitch = 1 alert(window.speechSynthesis) 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
演示了經過一個簡單的輸入框接收輸入的文字以及一個按鈕點擊後輸出語音的功能。
看一下
speak
函數:
function speak() {
speech.text = textToSpeech.value
speech.volume = 1
speech.rate = 1
speech.pitch = 1
window.speechSynthesis.speak(speech)
}
複製代碼
它實例化 SpeechSynthesisUtterance()
對象,將咱們在輸入框中輸入的文本轉換爲語音。而後,調用語音對象 SpeechSynthesis
的 speak
函數,使輸入框中的文本在咱們的揚聲器中放出。
第二個演示 Demo - Speech to Text
是語音識別演示。咱們點擊 Tap and Speak into Mic
按鈕,對着麥克風說話,咱們說的單詞就被翻譯成了文本。
Tap and Speak into Mic
按鈕單擊後調用 tapToSpeak
函數:
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()
}
複製代碼
很簡單,實例化 SpeechRecognition
,而後註冊事件處理程序和回調。在語音識別開始時調用 onstart
,在發生錯誤時調用 onerror
。每當語音識別捕獲到一條線時,就會調用 onresult
。
能夠看到,在 onresult
回調中,咱們提取文本並將其設置到文本區域。因此當咱們對着麥克風說話時,這些內容會輸出在文本區域中。
譯者:個人爪機和電腦 Chrome
(V83) 都不能支持該 API
。
實驗技術
Bluetooth API
使得咱們能夠訪問手機上的低功耗藍牙設備,並使用它來將網頁中的數據共享到另外一臺設備上。
想象一下可以建立一個Web聊天應用,該應用程序能夠經過藍牙發送和接收來自其餘手機的消息。
基礎 API
是 navigator.bluetooth.requestDevice
。調用它將使瀏覽器提示用戶選擇一個設備,使他們能夠選擇一個設備或取消請求。
navigator.bluetooth.requestDevice
須要一個對象。該對象定義了用於返回與過濾器匹配的藍牙設備的過濾器。
讓咱們看一個簡單的演示。本演示將使用 navigator.bluetooth.requestDeviceAPI
從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() {
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")
}
}
複製代碼
該 bluetoothAction
函數調用 navigator.bluetooth.requestDevice
API,參數設置爲 acceptAllDevices: true
,這將使其掃描並列出附近全部開啓了藍牙的設備。它返回的是一個 Promise
。
譯者注:電腦上 Chrome
瀏覽器上測試了下,是支持該API的。
Channel Messaging API
容許兩個不一樣的腳本運行在同一個文檔的不一樣瀏覽器上下文(好比兩個 iframe
,或者文檔主體和一個 iframe
,或者兩個 worker
)來直接通信,在每端使用一個端口(port
)經過雙向頻道(channel
)向彼此傳遞消息。。
首先建立一個 MessageChannel
實例:
new MessageChannel()
複製代碼
這將返回一個 MessagePort
對象(通信信道)。
而後,就能夠經過 MessagePort.port1
或 MessageChannel.port2
設置端口。
實例化 MessageChannel
的上下文將使用 MessagePort.port1
,另外一個上下文將使用 MessagePort.port2
。而後,就可使用 postMessage API
傳遞消息了。
每一個瀏覽器上下文都使用 Message.onmessage
監聽消息,並使用事件的 data
屬性獲取消息內容。
讓咱們看一個簡單的示例,在這裏咱們可使用 MessageChannel
在文檔和 iframe
之間發送文本。
譯者注:這個demo,原文中代碼有錯誤,譯者對代碼進行了修改,親測能夠正常運行
<body>
<header>
<h2>Web APIs<h2>
</header>
<div class="web-api-cnt">
<div class="web-api-card">
<div class="web-api-card-head"> Demo - MessageChannel </div>
<div class="web-api-card-body">
<div id="error" class="close"></div>
<div id="displayMsg">
</div>
<div>
<input id="input" type="text" placeholder="Send message to iframe" />
</div>
<div>
<button onclick="sendMsg()">Send Msg</button>
</div>
<div>
<iframe id="iframe" src="./iframe.content.html"></iframe>
</div>
</div>
</div>
</div>
</body>
<script> try { var channel = new MessageChannel() var port1 = channel.port1 } catch (e) { error.innerHTML = "MessageChannel API not supported in this device." error.classList.remove("close") } iframe.addEventListener("load", onLoad) function onLoad() { port1.onmessage = onMessage iframe.contentWindow.postMessage("load", '*', [channel.port2]) } function onMessage(e) { const newHTML = "<div>" + e.data + "</div>" displayMsg.innerHTML = displayMsg.innerHTML + newHTML } function sendMsg() { port1.postMessage(input.value) } </script>
複製代碼
注意 iframe
的標籤,咱們在上面加載了一個 iframe.content.html
文件。按鈕和文本是咱們鍵入文字並向 iframe
發送消息的地方。
const channel = new MessageChannel()
const port1 = channel.port1
iframe.addEventListener("load", onLoad)
function onLoad() {
port1.onmessage = onMessage
iframe.contentWindow.postMessage("load", '*', [channel.port2])
}
function onMessage(e) {
const newHTML = "<div>" + e.data + "</div>"
displayMsg.innerHTML = displayMsg.innerHTML + newHTML
}
function sendMsg() {
port1.postMessage(input.value)
}
複製代碼
咱們初始化了 MessageChannel
和 port1
。咱們向 iframe
添加了 load
監聽。在這裏,咱們在port1
註冊了 onmessage
監聽,而後使用 postMessageAPI
將消息發送到 iframe
。看到 port2
被向下發送到 iframe
。
讓咱們看一下
iframe
的iframe.content.html
:
<body>
<div class="web-api-cnt">
<div class="web-api-card">
<div class="web-api-card-head">
Running inside an <i>iframe</i>
</div>
<div class="web-api-card-body">
<div id="iframeDisplayMsg">
</div>
<div>
<input placeholder="Type message.." id="iframeInput" />
</div>
<div>
<button onclick="sendMsgiframe()">Send Msg from <i>iframe</i></button>
</div>
</div>
</div>
</div>
</body>
<script> var port2 window.addEventListener("message", function(e) { port2 = e.ports[0] port2.onmessage = onMessage }) function onMessage(e) { const newHTML = "<div>"+e.data+"</div>" iframeDisplayMsg.innerHTML = iframeDisplayMsg.innerHTML + newHTML } function sendMsgiframe(){ port2.postMessage(iframeInput.value) } </script>
複製代碼
在這裏,咱們註冊了一個消息事件處理函數。咱們檢索 port2
並在其上設置 onmessage
事件處理函數。如今,咱們能夠從 iframe
接收消息並將其發送到其父文檔。
譯者注:這個 try 不起來哈,能夠拷貝我上面的代碼在本地嘗試
大多數現代移動設備包括振動硬件,其容許軟件代碼經過使設備搖動來向用戶提供物理反饋。Vibration API
爲 Web
應用程序提供訪問此硬件(若是存在)的功能,若是設備不支持此功能,則不會執行任何操做。
navigator.vibrate(pattern)
控制振動,pattern
是描述振動模式的單個數字或數字數組。
navigator.vibrate(200);
navigator.vibrate([200]);
複製代碼
以上兩個例子均可以使設備振動 200 ms 並中止.
navigator.vibrate([200,300,400])
複製代碼
這將使設備振動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
等。
BroadcastChannel
類用於建立或加入頻道。
const politicsChannel = new BroadcastChannel("politics")
複製代碼
politics
將是頻道的名稱。任何經過 politics
來初始化 BroadcastChannel
構造函數的上下文都將加入頻道,它將接收在該頻道上發送的任何消息,而且能夠將消息發送到該頻道。
若是是第一個使用 BroadcastChannel
的構造函數,politics
則會建立該頻道。
要發佈到頻道,請使用 BroadcastChannel.postMessageAPI
要訂閱頻道(收聽消息),請使用該 BroadcastChannel.onmessage
事件。
爲了演示廣播頻道的用法,我構建了一個簡單的聊天應用程序:
<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>
複製代碼
初始化了 politicsChannel
,並在 politicsChannel
上設置了一個 onmessage
事件監聽器,以便它能夠接收和顯示消息。
點擊按鈕時,會調用 sendMsg
函數。它經過 BroadcastChannel#postMessageAPI
將消息發送到 politicsChannel
。初始化相同腳本的 tab
頁,iframe
或 worker
都將接收今後處發送的消息,所以該頁面能夠接收其餘上下文發送的消息。
Payment Request API
提供了爲商品和服務選擇支付途徑的方法。
該 API
提供了一種一致的方式來向不一樣的商家提供付款細節,而無需用戶再次輸入細節。
它向商家提供帳單地址,收貨地址,卡詳細信息等信息。
注意: 此 API
提供了用戶付款明細,但並不會帶來新的付款方式。
讓咱們看一個演示如何使用付款請求
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 - Credit Card Payment </div>
<div class="web-api-card-body">
<div id="error" class="close"></div>
<div>
<button onclick="buy()">Buy</button>
</div>
</div>
</div>
</div>
</body>
<script> const networks = ["visa", "amex"] const types = ["debit", "credit"] const supportedInstruments = [ { supportedMethods: "basic-card", data: { supportedNetworks: networks, supportedTypes: types } } ] const details = { total: { label: "Total", amount: { currency: "USD", value: "100" } }, displayItems: [ { label: "Item 1", amount: { currency: "USD", value: "50" } }, { label: "Item 2", amount: { currency: "USD", value: "50" } }, ] } try { var paymentRequest = new PaymentRequest(supportedInstruments, details) } catch (e) { error.innerHTML = "PaymentRequest API not supported in this device." error.classList.remove("close") } function buy() { paymentRequest.show().then(response => { console.log(response) }) } </script>
複製代碼
networks
,types
和 supportedTypes
都是描述付款方式。details
列出了咱們的購買商品和總費用。
構建 PaymentRequest
實例,paymentRequest.show()
將在瀏覽器中顯示付款界面。並在 Promise
成功的回調中處理用戶的數據。
它們是使用 Payment API
進行付款的許多配置,至少經過上面的示例,咱們已經瞭解了 Payment Request API
的使用方式和工做方式。
譯者注:測試了下,可是沒有走徹底流程,畢竟我堅定不付款的~
Resize Observer API
提供了一種方式,以任何方式調整了註冊觀察者的元素的大小,都通知觀察者。
ResizeObserver
類提供了一個觀察器,該觀察器將在每一個 resize
事件上調用。
const resizeObserver = new ResizeObserver(entries => {
for(const entry of entries) {
if(entry.contentBoxSize)
consoleo.log("element re-sized")
}
})
resizeObserver.observe(document.querySelector("div"))
複製代碼
每當調整 div
大小時,控制檯上都會打印 "element re-sized"
。
讓咱們看一下如何使用
Resize Observer 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 - ResizeObserver
</div>
<div class="web-api-card-body">
<div id="error" class="close"></div>
<div id="stat"></div>
<div id="resizeBoxCnt">
<div id="resizeBox"></div>
</div>
<div>
<span>Resize Width:<input onchange="resizeWidth(this.value)" type="range" min="0" max="100" value="0" /></span>
</div>
<div>
<span>Resize Height:<input onchange="resizeHeight(this.value)" type="range" min="0" max="100" value="0" /></span>
</div>
</div>
</div>
</div>
</body>
<script> try { var resizeObserver = new ResizeObserver(entries => { for(const entry of entries) { stat.innerHTML = "Box re-sized. Height:" + entry.target.style.height + " - Width:" + entry.target.style.width } }) resizeObserver.observe(resizeBox) } catch(e) { error.innerHTML = "ResizeObserver API not supported in this device." error.classList.remove("close") } function resizeWidth(e) { resizeBox.style.width = `${e}px` } function resizeHeight(e) { resizeBox.style.height = `${e}px` } </script>
複製代碼
咱們在這裏有範圍滑塊。若是咱們滑動它們,它們將改變 idv#resizeBox
的寬高。咱們在div#resizeBox
上註冊了 ResizeObserver
觀察器,指示該消息指示框已被調整大小以及其高度和寬度的當前值。
嘗試滑動範圍滑塊,你將看到 div#resizeBox
寬高的變化,此外,咱們還將看到 div#stat
框中顯示的信息。
Pointer Lock API
對於須要大量的鼠標輸入來控制運動,旋轉物體,以及更改項目的應用程序來講很是有用。對高度視覺化的應用程序尤爲重要,例如那些使用第一人稱視角的應用程序,以及 3D 視圖和建模。
方法:
requestPointerLock
:此方法將從瀏覽器中刪除鼠標併發送鼠標狀態事件。這將持續到調用 document.exitPointerLock
爲止。document.exitPointerLock
:此 API
釋放鼠標指針鎖定並恢復鼠標光標。讓咱們來看一個例子:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style> #box { background-color: green; width: 100%; height: 400px; position: relative; } #ball { border-radius: 50%; background-color: red; width: 50px; height: 50px; position: absolute; } </style>
</head>
<body>
<header>
<h2>Web APIs<h2>
</header>
<div class="web-api-cnt">
<div class="web-api-card">
<div class="web-api-card-head"> Demo - PointerLock </div>
<div class="web-api-card-body">
<div id="error" class="close"></div>
<div id="box">
<div id="ball"></div>
</div>
</div>
</div>
</div>
</body>
<script> const l = console.log box.addEventListener("click", () => { if (box.requestPointerLock) box.requestPointerLock() else { error.innerHTML = "PointerLock API not supported in this device." error.classList.remove("close") } }) document.addEventListener("pointerlockchange", (e) => { document.addEventListener("mousemove", (e) => { const { movementX, movementY } = e ball.style.top = movementX + "px" ball.style.left = movementY + "px" }) }) </script>
</html>
複製代碼
在 div#box
中咱們有一個 div#box
和 div#ball
。
咱們在 div#box
上設置了一個 click
事件,當單擊它時會調用 requestPointerLock()
,這會使光標消失。
PointerLock
有一個 pointerlockchange
事件監聽器。當指針鎖定狀態更改時,將觸發此事件。在其回調中,咱們將其添加到 mousemove
事件。在當前瀏覽器選項卡上移動鼠標時,將觸發其回調。在此回調中,所以咱們使用它來獲取鼠標的當前X和Y位置。使用此信息,咱們能夠設置 div#ball
的 top
和 left
樣式屬性,所以,當鼠標移動時,咱們會看到一個跳舞的球(譯者注:原文的demo中沒有設置div#ball
的定位,所以修改 top
和 left
值時,小球位置沒有變化)。
鼠標事件的兩個新參數 —— movementX
和 movementY
提供了鼠標位置的變化狀況。當指針鎖定被啓動以後,正常的 MouseEvent
屬性 clientX
, clientY
, screenX
, 和 screenY
,保持不變,就像鼠標沒有在移動同樣。
譯者注:這個demo有點問題,所以try不起來,你們能夠拷貝我上面的代碼在本地 try.
Web日趨複雜。愈來愈多的原生功能正在使用中,這是由於Web用戶的數量遠遠大於原生APP用戶。用戶在原生應用上的體驗被帶到Web上,這樣他們無需去使用原生應用。
好嘛,若是看到這裏,說明是真愛了。要不要給個人 Github 增長一個 star。
若有翻譯不當的地方,多多包涵,歡迎在評論區指正~