天天看點

你可能不知道的JavaScript APIs

作者:猿來猿往

最近,看到一些好用但不太常用的JS API,覺得挺不錯的,分享給大家。

  • Page Visibility API
  • Web Share API
  • Broadcast Channel API
  • Internationalization API

下面,我們來看下應該在哪裡使用它們,以及如何使用它們。

Page Visibility API

這個APi 可以讓我們知道使用者何時離開了頁面。準确地說,隻要頁面的可見性狀态發生變化,無論是使用者最小化、最大化視窗還是切換标簽,該API都會觸發一個事件 visibilitychange 。

在過去,我不得不使用一些黑科技來确認使用者是否切換了标簽或最小化了視窗。最流行的是使用blur和foucs浏覽器事件。

window.addEventListener("focus", function () {
    // User is back on the page
    // Do Something
});

window.addEventListener("blur", function () {
    // User left the page
    // Do Something
});

           

上面的代碼可以工作,但不像預期的那樣。因為blur事件是在頁面失去焦點時觸發的,是以當使用者點選搜尋欄、警報對話框、控制台或視窗邊框時,它就會被觸發。是以,blur和foucs隻告訴我們頁面是否被激活,但不告訴我們頁面的内容是否被隐藏或可見。

案例

一般來說,我們希望使用 Page Visibility API,在使用者沒有看到頁面時停止不必要的程序,或者執行一些背景操作。可以下面這幾種情況:

  • 當使用者離開頁面時,暫停視訊、輪播圖或動畫。
  • 停止一些實時擷取資料的API
  • 發送一些使用者資訊

如何使用它?

Page Visibility API 有兩個屬性和一個事件來通路頁面可見性狀态。

document.hidden它是全局可用的,而且是隻讀的。盡量避免使用它,因為它現在已經被廢棄了,但是當被通路時,如果頁面是隐藏的,它将傳回 true,如果是可見的,它将傳回 false。

Document.visibilityState (隻讀屬性)

傳回document的可見性,即目前可見元素的上下文環境。由此可以知道目前文檔 (即為頁面) 是在背後,或是不可見的隐藏的标簽頁,或者 (正在) 預渲染。可用的值如下:

  • 'visible' : 此時頁面内容至少是部分可見。即此頁面在前景标簽頁中,并且視窗沒有最小化。
  • 'hidden' : 此時頁面對使用者不可見。即文檔處于背景标簽頁或者視窗處于最小化狀态,或者作業系統正處于 '鎖屏狀态'
  • 'prerender' : 頁面此時正在渲染中,是以是不可見的 (considered hidden for purposes of document.hidden). 文檔隻能從此狀态開始,永遠不能從其他值變為此狀态。

visibilitychange

當其頁籤的内容變得可見或被隐藏時,會在文檔上觸發 visibilitychange (能見度更改) 事件。

document.addEventListener("visibilitychange", () => {
    if (document.visibilityState === "visible") {
        // page is visible
    } else {
        // page is hidden
    }
});

           

Web Share API

Web Share API 它可以讓我們通路作業系統的本地共享機制,這對移動使用者特别有用。通過這個API,可以分享文本、連結和檔案,而不需要建立自己的分享機制或使用第三方的機制。

使用案例

可以用它來分享網頁上的内容到社交媒體上,或者把它複制到使用者的剪貼闆上。

如何使用它?

網絡共享API給了我們兩個接口來通路使用者的共享系統。

navigator.canShare(data);

如果對 Navigator.share() 的調用成功,則 Web Share API 的 Navigator.canShare() 方法将傳回 true。data 包含要共享的資料的對象,該對象要與 Navigator.share() 方法傳遞的資料相比對。

navigator.share(data)

Navigator.share() 方法通過調用本機的共享機制作為 Web Share API 的一部分。如果不支援 Web Share API,則此方法為 undefined。

data 包含要共享的資料的對象。必須至少指定以下字段之一。可用選項包括:

  • url: 要共享的 URL( USVString )
  • text: 要共享的文本( USVString )
  • title: 要共享的标題( USVString)
  • files: 要共享的檔案(“FrozenArray”)

該方法将會傳回一個 Promise。一旦使用者完成分享,這個 promise 将會接受。如果指定的共享資料格式不正确,promise 将會立即拒絕;如果使用者取消了分享,promise 也會拒絕。

事例

navigator.share({
  title: document.title,
  text: 'Hello World',
  url: 'https://developer.mozilla.org',
}); // 分享 MDN 的 URL

           

Broadcast Channel API

Broadcast Channel API 可以實作同 源 下浏覽器不同視窗,Tab 頁,frame 或者 iframe 下的 浏覽器上下文 (通常是同一個網站下不同的頁面) 之間的簡單通訊。

const broadcast = new BroadcastChannel("new_channel");
           

BroadcastChannel 接口非常簡單。通過建立一個 BroadcastChannel 對象,一個用戶端就加入了某個指定的頻道。隻需要向 構造函數 傳入一個參數:頻道名稱。如果這是首次連接配接到該廣播頻道,相應資源會自動被建立。

發送消息

現在發送消息就很簡單了,隻需要調用 BroadcastChannel 對象上的 postMessage() 方法即可。該方法的參數可以是任意對象。最簡單的例子就是發送 DOMString 文本消息:

broadcast.postMessage("Example message");
           

不隻是 DOMString,任意類型的對象都可以被發送。

斷開連接配接

通過調用 BroadcastChannel 對象的 close() 方法,可以離開頻道。這将斷開該對象和其關聯的頻道之間的聯系,并允許它被垃圾回收。

// 斷開頻道連接配接
bc.close()
           

Internationalization API

在開發一個網頁或應用程式時,需要将其内容翻譯成其他語言以覆寫更廣泛的閱聽人是非常常見的。然而,僅僅将你的網頁文本翻譯成你所需要的任何語言,并不足以使你的内容對講該語言的人可用,因為像日期、數字、機關等東西在不同國家是不同的,可能會給你的使用者帶來混亂。

假設你想在你的網頁上顯示日期 "2022年11月8日",如 "11/8/22"。根據讀者的國家,這個資料可以用三種不同的方式來閱讀。

  • “November 8, 2022” 或者 MM/DD/YY 來自美國
  • “August 11, 2022” or DD/MM/YY 來自歐洲
  • “August 22, 2011” or YY/MM/DD 來自中國、日本。

這就是國際化API(或I18n API)來解決不同語言和地區的格式問題的地方。I18n API是一個了不起的工具,有多種用途,但這裡不會深入研究,以免使本文過于冗長。

如何使用它?

I18n API 使用 locale 辨別符來工作。locales 參數必須是一個 BCP 47 語言标記的字元串,或者是一個包括多個語言标記的數組。如果 locales 參數未提供或者是 undefined,便會使用運作時預設的 locale。

一個 BCP 47 語言标記代表了一種語言或者區域(兩者沒有很大的差別)。在其最常見的格式中,它以這樣的順序囊括了這些内容:語言代碼,腳本代碼,和國家代碼,全部由連字元分隔開。例如:

  • "hi":印地語 (primary language)。
  • "de-AT": 在奧地利使用的德語 (primary language with country code)。
  • "zh-Hans-CN":在中國使用的簡體中文 (primary language with script and country codes)。

更準确地說,I18n API提供了一個Intl對象,它提供了精确的字元串對比、數字格式化,和日期時間格式化。Collator,NumberFormat 和 DateTimeFormat 對象的構造函數是 Intl 對象的屬性。本頁文檔内容包括了這些屬性,以及國際化使用的構造器和其他語言的方法等常見的功能。

Intl.Collator

collators 的構造函數,用于啟用對語言敏感的字元串比較的對象。

Intl.DateTimeFormat

用于啟用語言敏感的日期和時間格式的對象的構造函數。

Intl.ListFormat

啟用對語言敏感的清單格式化的對象的構造函數。

Intl.NumberFormat

用于啟用語言敏感數字格式的對象的構造函數。

Intl.PluralRules

用于啟用多種敏感格式和多種語言語言規則的對象的構造函數。

Intl.RelativeTimeFormat

用于啟用語言敏感的相對時間格式化的對象的構造函數。

在我們的例子中,我們重點關注 Intl.DateTimeFormat() 構造函數,以根據使用者的區域設定來格式化報價的 dateAdded 屬性。Intl.DateTimeFormat() 構造函數需要兩個參數:定義日期格式化慣例的 locale 字元串和用于自定義日期格式的 options 對象。

建立的 Intl.DateTimeFormat() 對象有一個 format() 方法,它需要兩個參數:我們要格式化的Date對象和用于自定義如何顯示格式化日期的 options 對象。

const logDate = (locale) => {
    const newDate = new Date("2022-10-24"); // YY/MM/DD
    const dateTime = new Intl.DateTimeFormat(locale, {timeZone: "UTC"});
    const formatedDate = dateTime.format(newDate);
    console.log(formatedDate);
};

logDate("en-US"); // 10/24/2022
logDate("de-DE"); // 24.10.2022
logDate("zh-TW"); // 2022/10/24
           

dateTime.format() 根據當地的日期格式約定改變日期。我們可以使用navigator.language全局屬性在報價單的日期上實作這一行為,該全局屬性持有使用者的首選區域設定。為此,我們将建立一個新的函數,接收一個日期字元串(YYYY-MM-DD格式),并根據使用者的locale傳回格式化的日期。

const formatDate = (dateString) => {
    const date = new Date(dateString);
    const locale = navigator.language;
    const dateTimeFormat = new Intl.DateTimeFormat(locale, {timeZone: "UTC"});

    return dateTimeFormat.format(date);

};
           

代碼部署後可能存在的BUG沒法實時知道,事後為了解決這些BUG,花了大量的時間進行log 調試,這邊順便給大家推薦一個好用的BUG監控工具 Fundebug。

繼續閱讀