10個打開了我新世界大門的 WebAPI

原來我對好多 Web API 一無所知,打開了我新世界的大門,將來 Web 能夠作到更多,早日一統江湖吧,吼吼吼。javascript

雖然這些 API 不少目前還存在兼容性的問題,可是仍是有必要了解一下的,文中的代碼,我已經都測試過了。但願你看完以後可以有所收穫。css

原文連接:blog.bitsrc.io/10-useful-w…html

你可能已經知道並使用更爲流行的 Web APIsWeb WorkerFetch等),但也有少數不那麼流行的 API,我我的喜歡使用,並建議你也嘗試一下。java

這篇文章中描述的全部 Web API 示例均可以在這裏找到:git

1. Web Audio API

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 設置聲像效果。最後,將節點鏈接到媒體源。

咱們有一個音量和聲像的滑塊,拖動它們會影響音量和音頻的聲像效果。

這個例子有問題,因此該連接也沒法正常使用,能夠拷貝上面的代碼在本地運行

try it

2. Fullscreen API

Fullscreen API MDN

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() ,從而返回到普通視圖。

try it

注:該連接中的視頻資源找不到了,可是全屏功能是正常的,你們也能夠在本地測試

3. Web Speech API

Web Speech API MDN

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() 對象,將咱們在輸入框中輸入的文本轉換爲語音。而後,調用語音對象 SpeechSynthesisspeak 函數,使輸入框中的文本在咱們的揚聲器中放出。

第二個演示 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 回調中,咱們提取文本並將其設置到文本區域。因此當咱們對着麥克風說話時,這些內容會輸出在文本區域中。

try it

譯者:個人爪機和電腦 Chrome(V83) 都不能支持該 API

4. Bluetooth API

Bluetooth API MDN

實驗技術

Bluetooth API 使得咱們能夠訪問手機上的低功耗藍牙設備,並使用它來將網頁中的數據共享到另外一臺設備上。

想象一下可以建立一個Web聊天應用,該應用程序能夠經過藍牙發送和接收來自其餘手機的消息。

基礎 APInavigator.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

try it

譯者注:電腦上 Chrome 瀏覽器上測試了下,是支持該API的。

5. Channel Messaging API

Channel Messaging API MDN

Channel Messaging API 容許兩個不一樣的腳本運行在同一個文檔的不一樣瀏覽器上下文(好比兩個 iframe,或者文檔主體和一個 iframe,或者兩個 worker)來直接通信,在每端使用一個端口(port)經過雙向頻道(channel)向彼此傳遞消息。。

首先建立一個 MessageChannel 實例:

new MessageChannel()
複製代碼

這將返回一個 MessagePort 對象(通信信道)。

而後,就能夠經過 MessagePort.port1MessageChannel.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)
}
複製代碼

咱們初始化了 MessageChannelport1 。咱們向 iframe 添加了 load 監聽。在這裏,咱們在port1 註冊了 onmessage 監聽,而後使用 postMessageAPI 將消息發送到 iframe 。看到 port2 被向下發送到 iframe

讓咱們看一下 iframeiframe.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 it

譯者注:這個 try 不起來哈,能夠拷貝我上面的代碼在本地嘗試

6. Vibration API

Vibration API MDN

大多數現代移動設備包括振動硬件,其容許軟件代碼經過使設備搖動來向用戶提供物理反饋。Vibration APIWeb 應用程序提供訪問此硬件(若是存在)的功能,若是設備不支持此功能,則不會執行任何操做。

navigator.vibrate(pattern) 控制振動,pattern 是描述振動模式的單個數字或數字數組。

navigator.vibrate(200);
navigator.vibrate([200]);
複製代碼

以上兩個例子均可以使設備振動 200 ms 並中止.

navigator.vibrate([200300400])
複製代碼

這將使設備振動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>
複製代碼

咱們有輸入和一個按鈕。在輸入框中輸入振動的持續時間,而後點擊按鈕。設備將在輸入的時間內振動

try it

譯者注:在安卓手機上測試正常

7. Broadcast Channel API

Broadcast Channel API MDN

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 頁,iframeworker 都將接收今後處發送的消息,所以該頁面能夠接收其餘上下文發送的消息。

Try it

8. Payment Request API

Payment Request API MDN

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>
複製代碼

networkstypessupportedTypes 都是描述付款方式。details 列出了咱們的購買商品和總費用。

構建 PaymentRequest 實例,paymentRequest.show() 將在瀏覽器中顯示付款界面。並在 Promise 成功的回調中處理用戶的數據。

它們是使用 Payment API 進行付款的許多配置,至少經過上面的示例,咱們已經瞭解了 Payment Request API 的使用方式和工做方式。

try it

譯者注:測試了下,可是沒有走徹底流程,畢竟我堅定不付款的~

9. Resize Observer API

Resize Observer API MDN

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 框中顯示的信息。

try it

10. Pointer Lock API

Pointer Lock API MDN

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#boxdiv#ball

咱們在 div#box 上設置了一個 click 事件,當單擊它時會調用 requestPointerLock(),這會使光標消失。

PointerLock 有一個 pointerlockchange 事件監聽器。當指針鎖定狀態更改時,將觸發此事件。在其回調中,咱們將其添加到 mousemove 事件。在當前瀏覽器選項卡上移動鼠標時,將觸發其回調。在此回調中,所以咱們使用它來獲取鼠標的當前X和Y位置。使用此信息,咱們能夠設置 div#balltopleft 樣式屬性,所以,當鼠標移動時,咱們會看到一個跳舞的球(譯者注:原文的demo中沒有設置div#ball的定位,所以修改 topleft 值時,小球位置沒有變化)。

鼠標事件的兩個新參數 —— movementXmovementY 提供了鼠標位置的變化狀況。當指針鎖定被啓動以後,正常的 MouseEvent 屬性 clientX, clientY, screenX, 和 screenY ,保持不變,就像鼠標沒有在移動同樣。

try it

譯者注:這個demo有點問題,所以try不起來,你們能夠拷貝我上面的代碼在本地 try.

總結

Web日趨複雜。愈來愈多的原生功能正在使用中,這是由於Web用戶的數量遠遠大於原生APP用戶。用戶在原生應用上的體驗被帶到Web上,這樣他們無需去使用原生應用。

好嘛,若是看到這裏,說明是真愛了。要不要給個人 Github 增長一個 star。

若有翻譯不當的地方,多多包涵,歡迎在評論區指正~

關注公衆號,加入技術交流羣

相關文章
相關標籤/搜索