关于javascript:你不知道的JavaScript-APIs

22次阅读

共计 10881 个字符,预计需要花费 28 分钟才能阅读完成。

前言

在本文中,将介绍一些鲜为人知但却十分有用的 API,如:

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

咱们将一起看看它们是什么,咱们应该在哪里应用它们,以及如何应用它们。

Page Visibility API

这是一个鲜为人知的 web API,在 JS 现状考察中,它的认知度排名倒数第四。它能够让你晓得用户何时来到了页面。精确地说,只有页面的可见性状态发生变化,无论是用户最小化、最大化窗口还是切换标签页,该 API 都会触发一个事件。

在过来,你不得不应用一些噱头来理解用户是否切换了标签页或最小化了窗口。最风行的形式是应用 blurfocus浏览器事件。应用这些事件会导致相似上面状况的产生:

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

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

后面的代码能够工作,然而不合乎预期。因为 blur 事件是在页面失去焦点时触发的,所以当用户点击搜寻栏、alert对话框、控制台或窗口边框时,它就会被触发。所以,blurfocus 只通知咱们页面是否被激活,但不通知咱们页面的内容是否被暗藏或显示。

什么时候应用

一般来说,咱们想要应用Page Visibility API,是心愿用来进行不必要的程序。比如说当用户没有看到页面时,或者执行后盾操作时。具体的场景能够是:

  • 当用户来到页面时暂停视频、图像旋转或动画;
  • 如果页面显示来自 API 的实时数据,在用户来到时临时进行实时显示的行为;
  • 发送用户剖析报告。

如何应用

Page Visibility API带来了两个属性和一个事件,用于拜访页面可见性状态:

  • document.hidden:该属性是全局可见并且只读。尽量避免应用该属性,因为当初曾经被废除了。当拜访该属性时,如果页面是暗藏状态则返回true,如果页面是可见状态则返回false
  • document.visibilityState:该属性是 document.hidden 更新后的版本。当拜访该属性时,会依据页面的可见性状态返回四个可能的值:

    • visible:该页面是可见的,或者精确地说,它没有被最小化,也不在另一个标签页。
    • hidden:该页面不可见,它是最小化的,或者在另一个标签页。
    • prerender:这是一个可见页面在预渲染时的初始状态。一个页面的可见性状态能够从 prerender 开始,而后扭转到另一个状态,但它不能从另一个状态扭转到prerender
    • unloaded:该页面正在从内存中卸载。
  • visibilitychange:这是一个由 document 对象提供的事件,当页面的 visibilityState 发生变化时被触发。
document.addEventListener("visibilitychange", () => {if (document.visibilityState === "visible") {// page is visible} else {// page is hidden}
});

为了理解如何应用Page Visibility API,让咱们用该个性来实现当用户来到页面时,暂停视频以及进行从 API 获取资源。首先,我将应用vite.js,它是一个疾速启动新我的项目的神奇工具:

npm create [email protected] unknown-web-apis

当被要求抉择一个框架时,抉择 vanilla 来创立一个 vanillajavascript 我的项目。实现之后,返回新文件夹,装置必要的npm 包并启动开发服务器:

cd unknown-web-apis
npm install
npm run dev

关上 localhost:3000/,你将看到你的 Vite 我的项目启动和运行!

首先,咱们间接跳转到 /main.js 文件并删除所有样板代码。其次,关上 /index.html,在id#appdiv 标签外部增加一个 video 元素,下面能够增加你想增加的任意视频文件。这里我应用了一只正在跳舞的耀西。

<div id="app">
    <video controls id="video">
        <source src="./yoshi.mp4" />
    </video>
</div>

回到 /main.js,咱们将向document 对象增加一个事件监听器,用来监听 visibilitychange 事件。而后当页面显示或暗藏时,咱们能够拜访 document.visibilityState 属性的值。

document.addEventListener("visibilitychange", () => {console.log(document.visibilityState);
});

你能够返回页面的控制台,当最小化窗口或者切换到另一个标签页时,查看页面可见性状态。当初,在事件监听器外部,咱们能够查看 document.visibilityState 属性,当属性值为 hidden 时暂停视频,当属性值为 visible 时播放视频。当然,咱们首先要应用 document.querySelector() 抉择 video 元素。

const video = document.querySelector("#video");

document.addEventListener("visibilitychange", () => {if (document.visibilityState === "visible") {video.play();
    } else {video.pause();
    }
});

当初,只有用户来到页面,视频就会进行。另一个应用 Page Visibility API 的场景是,当用户没有查看页面时,进行获取不必要的资源。为了看成果,咱们将编写一个函数不间断地从 quotable.io API 获取随机援用,并当页面暗藏时暂停该行为。首先,咱们将在 /index.html 创立一个新的 div 标签来存储援用。

<div id="app">
    <video controls id="video">
        <source src="./yoshi.mp4" />
    </video>
    <div id="quote"></div>
</div>

回到 /main.js,咱们应用 Fetch API 发动对quotable.io 端点 https://api.quotable.io/random 的调用,而后将后果插入到quotediv 中。

const quote = document.querySelector('#quote');

const getQuote = async () => {
  try {const response = await fetch('<https://api.quotable.io/random>');
    const {content, author, dateAdded} = await response.json();
    const parsedQuote = ` <q>${content}</q> <br> <p>- ${author}</p><br> <p>Added on ${dateAdded}</p>`;
    quote.innerHTML = parsedQuote;
  } catch (error) {console.error(error);
  }
};

让咱们简略地解释一下此处产生了什么。首先咱们从 DOM 中选中了 quote 元素。而后申明 getQuote 函数,该函数是一个异步函数,容许咱们应用 await 关键字进行期待,直到从 API 中获取到数据。获取的数据是 JSON 格局的,因而咱们再次应用 await 关键字来期待,直到数据被解析为 JavaScript 对象。

quotable.io的 API 为咱们提供了 contentauthordateAdded等属性,咱们把这些属性注入并显示在 quotediv 中。这样做是没问题的,然而援用只会获取一次,因而咱们能够应用setInterval() 每 10 秒来调用一次函数。

const quote = document.querySelector('#quote');

const getQuote = async () => {
  try {const response = await fetch('<https://api.quotable.io/random>');
    const {content, author, dateAdded} = await response.json();
    const parsedQuote = ` <q>${content}</q> <br> <p>- ${author}</p><br> <p>Added on ${dateAdded}</p>`;
    quote.innerHTML = parsedQuote;
  } catch (error) {console.error(error);
  }
};

getQuote();

setInterval(getQuote, 10000);

如果用户最小化窗口或者切换标签页,该页面依然会获取援用,创立没有必要的网络加载。为了解决这个问题,在获取援用之前咱们能够查看以后页面是否可见。

const getQuote = async () => {if (document.visibilityState === 'visible') {
    try {const response = await fetch('<https://api.quotable.io/random>');
      const {content, author, dateAdded} = await response.json();
      const parsedQuote = `
          <q>${content}</q> <br> 
          <p>- ${author}</p><br> 
          <p>Added on ${dateAdded}</p>`;
      quote.innerHTML = parsedQuote;
    } catch (error) {console.error(error);
    }
  }
};

getQuote();

setInterval(getQuote, 10000);

当初,咱们只会在页面对用户可见的状况下获取援用。

兼容性

广泛支持

Web Share API

这是什么

Web Share API也是最不为人所知的 API 之一,但却十分有用。它能够让你拜访操作系统的原生分享机制,这对挪动端用户特地有用。有了这个 API,你能够分享文本、链接和文件,而不须要创立你本人的分享机制或应用第三方的分享机制。

什么时候应用

用处曾经不言自明。你能够用它将你的页面内容分享到社交媒体上,或将其复制到用户的剪贴板上。

如何应用

Web Share API赋予咱们两个接口来拜访用户的分享零碎:

  1. navigator.canShare():承受你想分享的数据作为参数,并依据其是否可分享,来返回一个布尔参数。
  2. navigator.share():返回一个 promise,如果分享胜利的话,该promise 将会resolve。该接口会调用原生分享机制,并接管你想分享的数据作为参数。留神,它只能在用户按下链接或按钮时调用。也就是说,它须要 transient activation(刹时激活)。分享数据是一个能够具备以下属性的对象:

    • url:要分享的链接
    • text:要分享的文本
    • title:要分享的题目
    • files:示意要分享的 File 对象数组

为了理解如何应用该 API,咱们将回收先前的用例,做一个选项应用 Web Sharing API 来分享咱们的援用。首先,咱们必须在 /index.html 新增一个分享按钮:

<div id="app">
    <video controls id="video">
        <source src="./yoshi.mp4" />
    </video>
    <div id="quote"></div>
    <button type="button" id="share-button">Share Quote</button>
</div>

返回 /main.js 从 DOM 中抉择分享按钮。而后,创立 async 函数来分享想要分享的数据。

const shareButton = document.querySelector("#share-button");

const shareQuote = async (shareData) => {
    try {await navigator.share(shareData);
    } catch (error) {console.error(error);
    }
};

当初,咱们能够为 shareButton 元素增加 click 事件监听器,以此来调用 shareQuote 函数。shareData.text的值会是 quote.textContent 属性,shareData.url的值会是页面的 URL,也就是 location.href 属性。

const shareButton = document.querySelector("#share-button");

const shareQuote = async (shareData) => {
    try {await navigator.share(shareData);
    } catch (error) {console.error(error);
    }
};

shareButton.addEventListener("click", () => {
    let shareData = {
        title: "A Beautiful Quote",
        text: quote.textContent,
        url: location.href,
    };

    shareQuote(shareData);
});

当初你能够通过你的原生操作系统与任何人分享你的援用。然而,须要留神的是,Web Share API只有在上下文平安的状况下才会起作用,也就是说,页面是通过 https://wss:// URLs 提供的。

兼容性

根本不反对

Broadcast Channel API

这是什么

我想议论的另一个 API 是 Broadcast Channel API。它容许浏览器上下文相互发送和接管根本数据。浏览器上下文是指标签页、窗口、iframe 等元素,或任何能够显示页面的中央。出于平安考量,浏览器上下文之间的通信是不被容许的,除非它们是同源的并应用Broadcast Channel API。对于两个同源的浏览器上下文,它们的 URL 必须有雷同的协定(如http/https)、域(如example.com)和端口(如:8080)。

什么时候应用

Broadcast Channel API通常用于在不同的标签页和窗口之间放弃页面状态同步,以进步用户体验或出于平安起因思考。它也能够用来晓得一个服务在另一个标签页或窗口中何时实现。应用场景有:

  • 在所有标签页上登录或登记用户。
  • 检测资源何时上传,并在所有页面中展现它。
  • 批示 service worker 做一些幕后工作。

如何应用

Broadcast Channel API波及一个 BroadcastChannel 对象,该对象可用于向其余上下文发送信息。构造函数只有一个参数:作为标识符的字符串,该标识符从其余上下文连贯到频道。

const broadcast = new BroadcastChannel("new_channel");

一旦咱们在两个上下文中创立了具备雷同标识符的 BroadcastChannel 对象,这个新的 BroadcastChannel 对象将有两个可用的办法来开始进行通信:

  • BroadcastChannel.postMessage():在所有连贯的上下文中发送音讯。它承受任意类型的对象作为其惟一的参数,因而你能够发送各种各样的数据。

    broadcast.postMessage("Example message");
  • BroadcastChannel.close():敞开通道,向浏览器表明它不会再收到任何信息,这样它就能够把这些信息收集到垃圾回收中。

为了承受信息,BroadcastChannel有一个 message 事件,咱们能够应用 addEventListener 或其 onmessage 属性来监听。message事件有一个 data 属性,蕴含发送的数据和其余属性,以辨认发送音讯的上下文,如 originlastEventIdsourceports

broadcast.onmessage = ({data, origin}) => {console.log(`${origin} says ${data}`);
};

让咱们看看如何通过应用先前的例子来应用 Broadcast Channel API。咱们的指标是制作另一个具备同源的浏览器上下文,并在两个上下文中展现雷同的援用。为了做到这一点,咱们将创立一个名为new-origin 的新文件夹,外面有一个新的 /index.html/main.js文件。

/new-origin/index.html将是一个新的 HTML 模板,外面有一个#quotediv:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <link rel="icon" type="image/svg+xml" href="../favicon.svg" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Vite App</title>
    </head>
    <body>
        <div id="quote"></div>
        <script type="module" src="./main.js"></script>
    </body>
</html>

/new-origin/main.js 文件中,咱们将创立一个新的 broadcast channel,并从 DOM 中抉择#quote 元素:

const broadcast = new BroadcastChannel("quote_channel");
const quote = document.querySelector("#quote");

在先前的 /main.js 文件中,咱们将创立新的 BroadcastChannel 对象,并连贯到 "quote_channel"。咱们还将批改getQuote 函数,将援用作为音讯发送到其余上下文。

const broadcast = new BroadcastChannel("quote_channel");

//...

const getQuote = async () => {
    try {const response = await fetch("<https://api.quotable.io/random>");
        const {content, author, dateAdded} = await response.json();
        const parsedQuote = ` <q>${content}</q> <br> <p>- ${author}</p><br> <p>Added on ${dateAdded}</p>`;
        quote.innerHTML = parsedQuote;
        broadcast.postMessage(parsedQuote);
    } catch (error) {console.error(error);
    }
};

回到 /new-origin/main.js 文件,咱们将监听 message 事件并在每次发送新的援用时扭转quote.innerHTML

const broadcast = new BroadcastChannel("quote_channel");
const quote = document.querySelector("#quote");

broadcast.onmessage = ({data}) => {quote.innerHTML = data;};

当初你能够看到 http://localhost:3000/new-origin/ 中的援用是如何变动为 http://localhost:3000 中的援用的。你也能够留神到,当 http://localhost:3000 标签被暗藏时,援用并没有扭转,因为它只在其页面可见性状态为可见时才会去获取援用。

兼容性

广泛支持

Internationalization API

这是什么

在开发一个网页或应用程序时,须要将其内容翻译成其余语言以笼罩更宽泛的受众是十分常见的。然而,仅仅将你的网页文本翻译成你所须要的任何语言,并不足以使你的内容对讲该语言的人可用,因为像日期、数字、单位等货色在不同国家是不同的,可能会给你的用户带来困惑。

咱们假如你想在你的网页上展现日期 ”2022 年 11 月 8 日 ”,就像 ”11/8/22″。依据读者所在的国家,这些数据能够用三种不同的形式来浏览:

  • “11/8/2022″ 或美国用户的 MM/DD/YY。
  • “8/11/2022″ 或欧洲和拉美用户的 DD/MM/YY。
  • “2011/8/22″ 或日本、中国和加拿大用户的 YY/MM/DD。

这就是 Internationalization API(或I18n API)来解决不同语言和地区的格局问题的中央。I18n API 是一个了不起的工具,有多种用处,但咱们不会深入研究,免得使本文过于简单。

如何应用

I18n API应用 locale 标识符来起作用。locale标识符是一个字符串,用来示意用户的语言、城市、地区、方言以及其余偏好。精确的说,locale标识符是一个字符串,由连字符分隔的子标签组成。子标签代表了用户偏好,比方语言、国家、地区或文字,并以以下形式格式化:

  1. "zh":中文(语言);
  2. "zh-Hant":用繁体字(文字)书写的中文(语言);
  3. "zh-Hant-TW":在台湾(地区)应用的繁体字(文字)书写的中文(语言)。

还有更多的子标签来解决更多用户的偏好(如果你想理解更多,你能够查看 RFC 对语言标签的定义),但简而言之,I18n API应用这些 locale 标识符来晓得如何格式化所有语言敏感的数据。

更确切地说,I18n API提供了一个 Intl 对象,它带来了一堆专门的构造函数来解决对语言敏感的数据。在我看来,一些对国际化最有用的 Intl 构造函数是:

  • Intl.DateTimeFormat():用于格式化日期和工夫。
  • Intl.DisplayNames():用于格式化语言、地区和文字显示名字。
  • Intl.Locale():用于构建和操作 locale 标识符标签。
  • Intl.NumberFormat():用于格式化数字。
  • 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

留神:在 Intl.DateTimeFormat 构造函数的 options 参数中,咱们将 timeZone 属性设置为 "UTC",这样日期就不会被格式化为用户的当地工夫。在我的例子中,没有timeZone 的选项,日期被解析为 “10/23/2022″。

正如你所看到的,dateTime.format()依据 locale 的日期格局约定扭转日期。咱们能够应用 navigator.language 全局属性在援用的日期上实现这一行为,该全局属性具备用户的首选 locale 设置。为此,咱们将创立一个新的函数,接管一个日期字符串(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);

};

咱们能够在 getQuote() 函数中增加这个函数来解析 dateAdded 日期。

const getQuote = async () => {if (document.visibilityState === "visible") {
        try {const response = await fetch("<https://api.quotable.io/random>");
            const {content, author, dateAdded} = await response.json();
            const parsedQuote = `
            <q>${content}</q> <br> 
            <p>- ${author}</p><br> 
            <p>Added on ${formatDate(dateAdded)}</p>`;
            quote.innerHTML = parsedQuote;
            broadcast.postMessage(parsedQuote);
        } catch (error) {console.error(error);
        }
    }
};

有了这个,咱们的援用就被本地化为用户的首选语言了!在我的例子中,我的 navigator.language 值是"en",所以我的日期被格式化为 MM/DD/YY。

兼容性

广泛支持

总结

读完这篇文章后,你当初能够灵便地理解这些 API 的存在以及如何应用它们。只管它们在 JS 现状考察中的认知度排名最初,但它们十分有用,晓得如何应用它们必定会进步你的开发教训。这些弱小的 API 并不为人所知,这意味着还有一些你我都不晓得的有用的 API,所以当初是摸索并找到那个能够简化你的代码,并为你节俭大量开发工夫的 API 的最佳时机。

以上就是本文的所有内容,如有对你有所帮忙,欢送点赞珍藏转发~

正文完
 0