整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          JavaScript - Fetch API 完全手冊

          果您想從 API 加載數據,那么 fetch API 是在 JavaScript 中執行此操作的最佳方式。您不需要引入任何第三方庫,就可以直接使用方便的fetch。

          像上圖所示,絕大多數瀏覽器已經原生支持Fetch,所以您可以放心使用。Node.js 對它的支持也正在路上,Fetch 已經作為 Node v17 中的實驗性功能提供,你可以使用 node app.js --experimental-fetch 來開啟它。

          Fetch API 的基本使用

          Fetch API 是基于Promise的,所以如果你不了解Promise, 最好先學習一下Promise。

          調用 fetch API 的最簡單方法是將 URL 傳遞給 fetch 函數。

          這將返回一個包含響應數據的Promise。此響應數據包含狀態屬性以及將原始響應數據轉換為 JSON、文本或其他格式的方法。

          上面顯示res.json() 是在我們的響應中調用 json() 方法,這個方法會返回另外一個 promise,該 promise 從我們的響應中解析 JSON 數據。

          我們可以在后面的then方法中獲取到最終需要的JSON數據對象。

          如果您從 JSON api 獲取數據,這就是大多數獲取請求的樣子。 我們首先獲取 URL,然后將響應轉換為 JSON,最后使用最終 .then 中的數據。

          如果使用async/await語法,可能會更簡單點。

          Fetch 參數

          這將涵蓋您的一些 fetch 用途,但通常您需要傳遞其他選項來進行 fetch 配置。 fetch 函數采用第二個選項對象參數,其中包含大量潛在選項。

          method

          最常用的選項是方法選項。 此選項允許您設置要使用的 HTTP 動詞(GET、POST、PUT、DELETE 等)。

          body

          如果您正在修改方法,那么您可能需要將數據與您的請求一起傳遞。 這就是 body 選項的用武之地。body 不接受對象,因此如果您想將 JSON 傳遞給您的 API,您必須首先將其轉換為字符串。

          headers

          現在,執行上述操作可能看起來像是將 JSON 傳遞給 API 所需要做的一切,但這實際上是行不通的。 原因是您需要設置正確的標頭來告訴您的 API 您正在發送 JSON 信息。 此標頭選項允許您設置所需的任何 HTTP 標頭。

          上面這組代碼是將 JSON 傳遞給 API 所需要做的一切。

          signal

          最后一個要說的的是信號選項。 這個選項接受一個 AbortSignal,它可以用來中止一個獲取請求。

          正如您從代碼中看到的那樣,這比其他選項要復雜一些。 首先你必須創建一個新的 AbortController 這個控制器有一個信號屬性,這是你傳遞給signal選項的。 控制器還有一個 abort 方法,當調用該方法時,將使用相關信號中止獲取請求。 這將導致 fetch Promise以 AbortError Reject異常。

          這些選項應該是可以cover你90%左右的用例。具體還有其他一些不常用的可以去查看官網文檔。

          總結:

          fetch API 是一個功能強大的工具,易于上手,它包含適用于每個可以想象的用例的許多高級選項。最重要的是,馬上node.js就可以原生支持它,邏輯可以前后端共享,豈不美哉!

          感謝閱讀!

          文介紹HTML5 <audio>音頻元素的屬性,方法,以及事件相關的API的基本使用。

          內容有些多,完整閱讀需要點時間,但很實用,可以先馬后看。

          一、audio使用基本案例

          <audio controls>
           <source src="audiofile.mp3" type="audio/mpeg">
           <source src="audiofile.ogg" type="audio/ogg">
           <!-- 如果瀏覽器不支持,則會呈現下面內容 -->
           <p>你的瀏覽器不支持HTML5音頻,你可以<a href="audiofile.mp3">下載</a>這個音頻文件。</p>
          </audio>
          

          上面做法是早些年HTML5 <audio>常用代碼,因為那時候IE8還是大頭,各大瀏覽器對各類音頻格式支持情況參差不齊,因此,才借助<source>元素同時引用多個不同格式的音頻文件,通過type屬性指定mime type避免重復加載情況出現。

          但是,如今已經不需要這么麻煩了。我們直接下面這樣就可以了:

          <audio src="audiofile.mp3" controls></audio>
          

          音頻文件常見下面3種格式,.ogg, .wav和.mp3,其中,.ogg Safari瀏覽器不支持(目前版本13),IE到Edge16都不支持;.wav則是IE-IE11不支持;但是.mp3 IE9+都支持。因此,我們如果不想麻煩,直接一個MP3格式就好了,由于就一種文件格式,因此type屬性也可以不用設置。

          //zxx: 也可以使用MP4視頻文件,因為MP4視頻也包含ACC編碼音頻,不過就是體積大了很多,不建議這么使用。

          <audio>元素IE9瀏覽器就開始支持,現在00后都快20歲了,也不需要為低版本瀏覽器做降級適配了。因此,簡簡單單一個<audio>元素就可以了。

          二、Audio HTML屬性

          下面看下<audio>元素屬性相關的一些細節。

          autoplay

          <audio src="audiofile.mp3" autoplay></audio>
          

          autoplay是個布爾屬性值,表示聲音是否自動播放,默認不自動播放。然而,隨著瀏覽器的發展,這個屬性變得限制越來越多。首先在移動端,autoplay自動播放已經被禁止了,PC端也已經禁止,18年的時候,Chrome這么做了,然后被很多開發者抗議,后來又恢復autoplay(給大家緩沖時間),現在已經Chrome又不支持自動播放了。

          原因是網頁在沒有警告的情況下自發地發出聲音,可能會讓用戶不愉快,體驗不太好。因此,瀏覽器通常只允許在特定情況下成功地進行自動播放。

          關于更深入的autoplay策略可以參見MDN上的這篇文檔。

          不過根據我自己的一些實踐,資源靜音或者視頻沒有聲音情況下,autoplay偶爾也是會執行的,不過都是偶現,觸發自動播放原因不詳。

          loop

          <audio src="audiofile.mp3" loop></audio>
          

          loop是個布爾屬性值,表示聲音是否循環播放,默認不循環播放。loop屬性適合用在可以不斷循環的bgm背景音樂上。loop屬性在各個平臺,各個瀏覽器下的表現良好,大家可以放心使用。

          JS設置音頻循環播放可以:

          document.querySelector('audio').loop = true;
          

          muted

          示意:

          <audio src="audiofile.mp3" muted></audio>
          

          muted也是個布爾屬性值,表示音頻是否靜音,默認不靜音播放。muted屬性在各個平臺,各個瀏覽器下的表現良好,大家可以放心使用。

          JS設置音頻靜音可以:

          document.querySelector('audio').muted = true;
          

          preload

          示意:

          <audio src="audiofile.mp3" preload="auto"></audio>
          

          preload可以指定音頻的預加載策略,也就是在播放之前需要提前加載好音頻的哪些資源。支持下面3個屬性值:

          1. none:表示在點擊播放按鈕之前不加載任何信息。
          2. metadata: 下載音頻的meta信息,就是視頻長度,類型,還有作者(如果有)等信息。/li>
          3. auto: 會嘗試下載整個音頻,如今5G都快來了,流量已經不值錢了,因此,我個人是更推薦使用auto的,體驗更好一點。然后,通常瀏覽器自己也會優化加載策略,不會所有音頻文件都加載下來,只是會加載一部分,保證點擊播放按鈕的時候,可以立即播放。

          preload屬性在iOS Safari瀏覽器下是被禁止的(桌面端無此問題),對于一些對音頻播放時間實際要求比較高的場合,會給我們開發帶來困難。通常解決方法是,第一次觸摸的時候,音頻靜音,同時觸發音頻play()然后很快再pause(),此時,可以有類似preload的預加載行為。

          不過,Safari以后可能會改變preload在移動端的加載策略,因為越往后流量越不值錢,這種自以為是的優化反而會成為一種桎梏。

          controls

          示意:

          <audio src="audiofile.mp3" controls></audio>
          

          controls是個布爾屬性值,表示聲音是否顯示音頻播放暫停等控制器,默認是不顯示的。

          如果沒有設置controls屬性,整個音頻文件播放面板都是完全隱藏的;如果有設置,則UI可能類似下面這張圖(Chrome PC,設置了靜音)。


          不同瀏覽器,以及不同版本瀏覽器,其UI都不一樣。如果是開發to用戶側產品,需要自定義音頻播放器的UI,讓各個瀏覽器下長相一致,大家可以去github上找找開源的項目。

          src

          示意:

          <audio src="audiofile.mp3"></audio>
          

          src屬性表示音頻的文件地址。可以用在<audio>元素上,也可以用在<source>元素上。<audio>元素上只能一個音頻地址,使用<source>可以并列多個不同格式的音頻文件。

          type

          <audio src="audiofile.mp3" type="audio/mpeg"></audio>
          

          type屬性用來指定音頻文件的mime type類型。雖然不加type類型,瀏覽器也能正確播放音頻文件,但通常建議加上type屬性。當然,如果src音頻格式不固定,則type屬性反而推薦不加,錯誤的type不如沒有type。

          三、在JS中調用的audio屬性

          <audio>元素還有一些屬性只能通過JavaScript設置,假設有HTML如下:

          <audio id="myAudio" src="audiofile.mp3"></audio>
          

          則:

          currentTime

          currentTime是一個可讀兼可寫的屬性,用來設置或獲取當前已經播放的時長,單位是秒。

          例如:

          // 獲取音頻已經播放時長
          var playedTime = myAudio.currentTime;
          

          如果音頻尚未開始播放,則playedTime的返回值是0。

          我們也可以通過設置currentTime屬性值,讓我們的音頻定位到我們希望的時間點進行播放,例如,從5秒那里開始播放,則:

          // 跳到5秒那里
          myAudio.currentTime = 5;
          

          volume

          volume也是一個可讀兼可寫的屬性,用來設置或獲取音頻的音量大小,范圍是0-1。

          例如,設置音量50%,則:

          // 設置音量50%
          myAudio.volume = 0.5;
          

          如果音頻文件設置了muted為true,則myAudio.volume的返回值是0。

          playbackRate

          playbackRate是一個可讀兼可寫的屬性,用來設置或獲取當前媒體文件的播放速率,值為數值,例如:

          // 獲取音頻播放速率
          var audioSpeed = audio.playbackRate;
          // 設置音頻設置播放速率為正常速度的1.5倍
          audio.playbackRate = 1.5;
          

          速率范圍

          根據文檔顯示,Gecko內核瀏覽器速率范圍是0.25到5.0,超出這個范圍就靜音。

          對于Chrome瀏覽器,我自己實地測試了下,速率上限居然可以到16,如下圖:


          然后,此屬性兼容性不錯,IE9+都支持。

          paused

          paused是一個只讀屬性,表示當前音頻是否處于暫停狀態。

          // true或false
          console.log(myAudio.paused);
          

          未播放或者播放暫停都會返回true。

          四、播放與暫停等JS方法

          play()

          音頻播放示意,沒有額外參數:

          myAudio.play();
          

          需要注意的是,目前在現代瀏覽器下,無論是桌面端還是移動端,執行myAudio.play()不總是有效果的。

          目前策略是,web網頁需要至少又一次可信任的用戶行為后,才能myAudio.play()播放才可以執行,否則會報錯。


          可信任的用戶行為包括touchstart觸摸或者click點擊。

          pause()

          音頻暫停示意,沒有額外參數:

          myAudio.pause();
          

          音頻元素是沒有stop()方法的,如果你想要實現音頻的stop()效果,可以先設置currentTime屬性值為0,然后在執行pause()方法。

          canPlayType()

          canPlayType()可以用來檢測瀏覽器是否支持某種類型的音頻文件,支持一個mime type值作為參數。使用示意:

          if (myAudio.canPlayType('audio/mpeg')) {
           // 如果支持mp3
           // 這里搞事情
          }
          

          canPlayType()方法可以返回下面三個值中的某一個:

          1. probably
          2. maybe
          3. ""(空字符串)

          實際開發的時候,只要不是空字符串,我們都可以認為是支持的,因此,直接使用if弱匹配返回值即可,例如:

          var myAudio = document.createElement('audio');
          if (myAudio.canPlayType('audio/mpeg')) {
           myAudio.setAttribute('src','audiofile.mp3');
          }
          if (myAudio.canPlayType('audio/ogg')) {
           myAudio.setAttribute('src','audiofile.ogg');
          }
          

          load()

          觸發音頻文件的加載。如果瀏覽器不支持preload屬性,則此方法也不會有效果。

          此方法沒有額外參數:

          myAudio.load();
          

          五、音頻媒體加載事件

          下面講講關于音頻加載及相關處理,根據我實際項目中的實踐,這類加載事件在移動端,尤其iOS Safari并不總能觸發,因為preload以及autoplay等屬性的限制。

          loadstart

          loadstart事件簡單地告訴我們加載過程已經開始,瀏覽器正在連接到媒體。

          myAudio.addEventListener("loadstart", function() {
           // 抓取文件
          });
          

          durationchange

          如果你想盡快知道音頻文件的播放時長,則durationchange事件非常管用,因為音頻文件默認duration初始值是NaN,當準確時長返回時候,會觸發durationchange,此時我們就可以快速顯示音頻播放時間了。

          通常實際開發,我們會使用00:00占位,durationchange事件觸發后在替換為準確的總播放時間。

          myAudio.addEventListener("durationchange", function() {
           // 可以顯示播放時長了喲
          });
          

          loadedmetadata

          當第一個音頻文件字節數據到達時,會觸發loadeddata事件。雖然播放頭已經就位,但還沒有準備好播放。

          myAudio.addEventListener("loadeddata", function() {
           // 可以顯示播放頭
          });
          

          progress

          progress事件在媒體文件仍然在下載中的時候觸發,通常各種loading效果的顯示就是在這個事件中。

          myAudio.addEventListener("progress", function() {
           // 你可以讓用戶知道媒體文件正在下載
          });
          

          canplay

          當媒體文件可以播放的時候會觸發canplay事件。

          我們在自定義音頻播放器的時候,可以默認把一些按鈕disabled禁用,等可以播放的時候再恢復為enabled,此時就可以使用canplay事件。

          myAudio.addEventListener("canplay", function() {
           // 音頻可以播放了
          });
          

          canplaythrough

          canplaythrough事件在音頻文件可以從頭播放到尾時候觸發。這種情況包括音頻文件已經從頭到尾加載完畢了,或者瀏覽器認為一定可以按時下載,不會發生緩沖停止。

          myAudio.addEventListener("canplaythrough", function() {
           // 音頻可以不發生緩沖從頭播放到結束
          });
          

          音頻事件觸發的順序

          媒體事件加載順序如下:

          loadstart → durationchange → loadedmetadata → loadeddata → progress → canplay → canplaythrough

          加載中斷事件

          還有一些事件實在媒體加載過程出現某種中斷時將觸發。

          suspend

          即使文件尚未完全下載,也不再拉取媒體數據。

          abort

          不是因為出錯而導致的媒體數據下載中止。

          error

          媒體下載過程中錯誤。例如突然無網絡了。或者文件地址不對。

          emptied

          媒體緩沖區已被清空,可能是由于錯誤或調用了load()方法重新加載。

          stalled

          媒體數據意外地不再可用。

          六、音頻媒體播放事件

          下面介紹一些與媒體文件播放狀態相關的一些事件。

          timeupdate

          每次currentTime屬性值發生變化的時候會觸發timeupdate事件。

          實際開發的時候,這個事件每250毫秒出發一次。這個事件可用來實時顯示播放進度。

          myAudio.addEventListener("timeupdate", function() {
           // 更新與播放進度相關的內容
          });
          

          playing

          音頻文件在缺少媒體信息(如時長等)的時候,播放會被迫停止,如果之后在啟動播放,會觸發playing事件。

          waiting

          音頻文件因為缺少媒體信息(如時長等)導致播放停止時會觸發waiting事件。

          play

          play事件在play()方法生效,或者autoplay導致播放開始時候觸發,此事件觸發的播放狀態一定是一個從暫停到播放。

          pause

          pause事件在pause()方法執行并生效后觸發,此事件觸發需要一個從播放到暫停的狀態變化。

          ended

          當整個音頻文件播放完畢的時候觸發ended事件。

          myAudio.addEventListener("ended", function() {
           // 當音軌播放完畢時候做你想做的事情
          });
          

          volumechange

          音量發生變化的時候會觸發volumechange事件,包括靜音行為。

          ratechange

          播放速率發生變化的時候會觸發ratechange事件。

          七、緩沖相關的屬性和方法

          媒體文件的播放進度我們可以使用currentTime和duration屬性獲取,但是有時候,我們希望知道緩沖加載的進度,此時可以使用下面幾個和緩沖相關屬性和方法。

          buffered

          此屬性讓我們知道音頻的哪些部分已被緩沖(提前下載)。它返回一個稱為TimeRanges的對象。

          myBufferedTimeRanges = myAudio.buffered;
          

          seekable

          seekable屬性通知您是否可以直接跳到媒體的該部分,而不需要進一步緩沖。

          mySeekableTimeRanges = myAudio.seekable;
          

          Buffering相關事件

          seeking

          當媒體資源正在請求是會觸發seeking事件。

          seeked

          當seeking屬性變成false時候會觸發seeked事件。

          有關緩沖以及TimeRanges更深入具體的知識,可以參見這篇MDN文檔。

          八、結語與參考文檔

          本文展示的這些<audio>音頻元素相關的屬性和方法以及各種回調事件,對于<video>視頻元素同樣受用,基本上都是一模一樣的,很多自動播放以及媒體自動加載策略也是一致的。

          本文展示的這些API并不是全部,如果發現有遺漏,歡迎大家補充。

          載說明:原創不易,未經授權,謝絕任何形式的轉載

          Midjourney 創作,未來API

          大家好,隨著技術的迅速發展,開發者們擁有了越來越多的令人驚嘆的新工具和API。但是,我們發現在100多個API中,只有5%的API被開發者們積極地使用。

          下面讓我們來看看一些有用的Web API,它們可以幫助你將你的網站推向未來的巔峰!

          1、屏幕捕獲API

          屏幕捕獲API,正如其名,允許你捕獲屏幕內容,讓制作屏幕錄像變得輕而易舉。你需要一個視頻元素來顯示捕獲的屏幕。點擊開始按鈕即可開始屏幕捕獲。

          <video id="preview" autoplay>
            Your browser doesn't support HTML5.
          </video>
          <button id="start" class="btn">Start</button>
          // 獲取HTML元素
          const previewElem = document.getElementById("preview"); // 預覽元素
          const startBtn = document.getElementById("start"); // 開始按鈕元素
          
          // 異步函數,開始錄制屏幕和聲音
          async function startRecording() {
            previewElem.srcObject = // 將預覽元素的srcObject屬性設置為獲取到的屏幕和聲音媒體流
              await navigator.mediaDevices.getDisplayMedia({
                video: true, // 錄制視頻
                audio: true, // 錄制聲音
              });
          }
          
          // 為開始按鈕添加點擊事件監聽器,點擊時調用startRecording函數
          startBtn.addEventListener("click", startRecording);

          2、Web Share API

          Web Share API 允許你從一個網頁分享文本、鏈接甚至是文件到設備上安裝的其他應用程序。

          // 異步函數,處理分享事件
          async function shareHandler() {
            // 調用navigator.share方法進行分享,傳入分享內容的相關信息
            navigator.share({
              title: "Tapajyoti Bose | Portfolio", // 分享標題
              text: "Check out my website", // 分享文本
              url: "https://tapajyoti-bose.vercel.app/", // 分享鏈接
            });
          }
          
          // 給某個元素添加點擊事件監聽器,點擊時調用shareHandler函數
          someElement.addEventListener("click", shareHandler);

          注意:要使用 Web Share API,你需要從用戶那里獲得互動,例如按鈕點擊或觸摸事件。

          3、Intersection Observer API

          Intersection Observer API 允許你檢測元素何時進入或離開視口。這對于實現無限滾動非常有用。

          簡單的例子

          // 創建一個IntersectionObserver實例,觀察特定元素
          const observer = new IntersectionObserver((entries) => {
            // 遍歷每個entry,判斷是否在視口內
            entries.forEach((entry) => {
              if (entry.isIntersecting) {
                // 元素進入視口,執行相應操作
              } else {
                // 元素離開視口,執行相應操作
              }
            });
          });
          
          // 將需要觀察的元素傳遞給IntersectionObserver實例
          const target = document.querySelector(".target");
          observer.observe(target);

          一個復雜的分頁滾動(React版本)

          <div id="root"></div>
          /* The entire styling is totally optional */
          
          * {
            font-family: Roboto;
          }
          
          body {
            margin: 0;
            padding: 0;
            display: flex;
            flex-direction: column;
            align-items: center;
            text-align: center;
          }
          
          .item {
            width: 80vw;
            margin: 12px 0;
            padding: 32px;
            border-radius: 8px;
            font-size: larger;
          }
          
          .loader {
            border: 8px solid #cccccc;
            border-top: 8px solid #3498db;
            border-radius: 50%;
            width: 40px;
            height: 40px;
            animation: spin 0.6s linear infinite;
            display: inline-block;
            margin: 8px auto;
          }
          
          @keyframes spin {
            0% {
              transform: rotate(0deg);
            }
            100% {
              transform: rotate(360deg);
            }
          }
          
          // 聲明常量MAX_PAGES,表示可加載的最大頁數
          const MAX_PAGES = 5;
          
          // 生成隨機顏色的函數
          const generateRandomColor = () => {
            const characters = "0123456789ABCDEF";
            let color = "#";
            for (let i = 0; i < 6; i++) {
              color += characters[Math.floor(Math.random() * 16)];
            }
            return color;
          };
          
          // 定義Item組件,接受children、color和reference屬性,返回帶有顏色的div元素
          const Item = ({ children, color, reference }) => {
            return (
              <div className="item" style={{ backgroundColor: color }} ref={reference}>
                {children}
              </div>
            );
          };
          
          // 定義App組件
          const App = () => {
            // 定義狀態變量:items-加載的數據數組、isLoading-是否正在加載數據、hasMore-是否還有更多數據可加載、pages-已加載的頁數
            const [items, setItems] = React.useState([]);
            const [isLoading, setIsLoading] = React.useState(false);
            const [hasMore, setHasMore] = React.useState(true);
            const [pages, setPages] = React.useState(0);
          
            // 定義ref引用observer
            const observer = React.useRef();
          
            // 在掛載時更新items數組和pages變量
            React.useEffect(() => {
              updateItems();
              setPages((pages) => pages + 1);
            }, []);
          
            // 定義lastItemRef回調函數,用于觀察最后一個元素是否進入視口
            const lastItemRef = React.useCallback(
              (node) => {
                if (isLoading) return;
                if (observer.current) observer.current.disconnect();
          
                observer.current = new IntersectionObserver((entries) => {
                  if (entries[0].isIntersecting && hasMore) {
                    if (pages < MAX_PAGES) {
                      updateItems();
                      setPages((pages) => pages + 1);
                    } else {
                      setHasMore(false);
                    }
                  }
                });
          
                if (node) observer.current.observe(node);
              },
              [isLoading, hasMore]
            );
          
            // 定義updateItems異步函數,更新items數組和isLoading狀態變量
            const updateItems = async () => {
              setIsLoading(true);
              await new Promise((resolve) => setTimeout(resolve, 1000));
          
              setItems((currItems) => {
                const lastItem = currItems.length;
                const updatedItems = [...currItems];
                for (let i = 1; i <= 5; i++) {
                  const item = {
                    count: lastItem + i,
                    color: generateRandomColor()
                  };
                  updatedItems.push(item);
                }
                return updatedItems;
              });
          
              setIsLoading(false);
            };
          
            // 返回頁面結構
            return (
              <React.Fragment>
                <h1>Infinite Scroll Demo</h1>
                {items.map((item, index) =>
                  index + 1 === items.length ? (
                    <Item reference={lastItemRef} key={index} color={item.color}>
                      {item.count}
                    </Item>
                  ) : (
                    <Item key={index} color={item.color}>
                      {item.count}
                    </Item>
                  )
                )}
                {isLoading && <div className="loader" />}
              </React.Fragment>
            );
          };
          
          // 將App組件渲
          

          注意:此示例使用React,因為這是我個人偏好,但你可以使用任何框架或原生JavaScript。

          4、Clipboard API

          Clipboard API 允許你讀取和寫入剪貼板中的數據。這對于實現復制到剪貼板的功能非常有用。

          // 定義異步函數copyHandler,將指定文本寫入剪貼板
          async function copyHandler() {
            const text = "https://tapajyoti-bose.vercel.app/";
            navigator.clipboard.writeText(text);
          }
          

          5、Screen Wake Lock API

          你是否曾經想過在觀看視頻時如何防止屏幕關閉?這就是因為使用了 Screen Wake Lock API。

          // 聲明變量wakeLock
          let wakeLock = null;
          
          // 定義異步函數lockHandler,請求屏幕喚醒鎖定
          async function lockHandler() {
            wakeLock = await navigator.wakeLock.request("screen");
          }
          
          // 定義異步函數releaseHandler,釋放屏幕喚醒鎖定
          async function releaseHandler() {
            await wakeLock.release();
            wakeLock = null;
          }
          
          // 注意:只有頁面已經在屏幕上可見時,才能使用Screen Wake Lock API。否則會拋出錯誤。

          6、Screen Orientation API

          Screen Orientation API 允許你檢查屏幕的當前方向,甚至鎖定到特定的方向。

          // 定義異步函數lockHandler,鎖定屏幕方向為豎屏
          async function lockHandler() {
            await screen.orientation.lock("portrait");
          }
          
          // 定義函數releaseHandler,解除屏幕方向鎖定
          function releaseHandler() {
            screen.orientation.unlock();
          }
          
          // 定義函數getOrientation,返回屏幕當前的方向
          function getOrientation() {
            return screen.orientation.type;
          }
          

          7、Fullscreen API

          Fullscreen API 允許你將一個元素或整個頁面顯示為全屏。

          // 定義異步函數enterFullscreen,將整個文檔元素進入全屏模式
          async function enterFullscreen() {
            await document.documentElement.requestFullscreen();
          }
          
          // 定義異步函數exitFullscreen,退出全屏模式
          async function exitFullscreen() {
            await document.exitFullscreen();
          }
          
          // 注意:為了使用 Fullscreen API,同樣需要用戶的交互。

          注意:同樣需要用戶的交互才能使用 Fullscreen API。

          兼容性

          這些API,目前在主流瀏覽器中都得到了很好的支持,包括Google Chrome、Mozilla Firefox、Safari和Microsoft Edge等瀏覽器。但是,在舊版瀏覽器中可能會存在一些兼容性問題。因此,在開發使用時,應該考慮到不同瀏覽器的兼容性問題,并根據實際情況選擇是否使用這些API。

          結束

          非常棒!通過本文的介紹和代碼示例,相信大家已經了解了這些有用的Web API,并且知道如何使用它們來提升網站的用戶體驗和功能。雖然這些API在不同瀏覽器中的兼容性可能存在一些問題,但我們可以通過適當的兼容性檢查和回退方案來確保網站的穩定性和可靠性。總之,Web API為開發者提供了強大的工具和資源,讓我們一起探索并不斷嘗試新的技術和功能,為用戶帶來更好的體驗和價值。

          今天的分享就到這里,感謝你的閱讀,希望能夠幫助到你,文章創作不易,如果你喜歡我的分享,別忘了點贊轉發,讓更多有需要的人看到,最后別忘記關注「前端達人」,你的支持將是我分享最大的動力,后續我會持續輸出更多內容,敬請期待。

          原文:https://tapajyoti-bose.medium.com/7-javascript-web-apis-to-build-futuristic-websites-you-didnt-know-12b737ccf594

          作者:Tapajyoti Bose

          非直接翻譯,有自行改編和添加部分,翻譯水平有限,難免有疏漏,歡迎指正


          主站蜘蛛池模板: 国产Av一区二区精品久久| 91精品福利一区二区| 韩国理伦片一区二区三区在线播放| 日韩一区二区三区不卡视频| 精品无码一区二区三区亚洲桃色| 一区二区三区精品视频| 日韩在线视频一区| 2021国产精品视频一区| 精品久久一区二区| 国精产品一区一区三区免费视频 | 国内精品一区二区三区在线观看 | 亚洲丰满熟女一区二区哦| 久久久精品人妻一区二区三区 | 天堂资源中文最新版在线一区| 中文乱码精品一区二区三区| 欧洲精品一区二区三区在线观看| 日韩高清一区二区| 国产第一区二区三区在线观看| 怡红院一区二区在线观看| 国产精品久久久久久一区二区三区 | 午夜福利一区二区三区在线观看 | 丰满岳妇乱一区二区三区| 日韩伦理一区二区| 日本一区二区三区在线网| 后入内射国产一区二区| 色视频综合无码一区二区三区| 成人国产精品一区二区网站| 一区二区高清在线| 国产一区二区不卡在线播放| 日本一区二区在线| 国产电影一区二区| 无码日韩AV一区二区三区| 搜日本一区二区三区免费高清视频| 一区二区三区在线观看免费| 国产一区三区二区中文在线| 亚洲一区二区三区偷拍女厕| 精品黑人一区二区三区| 国产成人av一区二区三区在线观看| 亚洲一区视频在线播放| 国产AV午夜精品一区二区入口| 亚洲香蕉久久一区二区三区四区|