2023-08前端新活汇总

信源:

  • https://web.dev/
  • 前端食堂
  • MDN Blog
  • Google I/O
  • Google Developers

部分可用的内容

虚拟键盘 API

来自 前端食堂

FireFox NA, Chrome 94, Edge 94, Safari NA

介绍了移动端中弹出键盘造成页面上移部分元素无法显示的问题. 通过

body:has(input:focus) {
  padding-bottom: calc(
    var(--cta-height) + env(keyboard-inset-height, 0)
  );
}

的方法实现当用户聚焦 input 时将元素移动位置从而规避遮盖的问题.

这里使用 env() 实现环境检测, 即: 若存在 keyboard-inset-height 则使用, 否则使用 0px

浏览器八月特性

  • Audio Output Devices API

    来自 MDN FireFox 116, Chrome NA, Edge NA, Safari NA

    允许用户在浏览器中选择音频播放设备 (扬声器, 蓝牙耳机...), 就像在操作系统中选择播放设备一样

    // 选择播放设备的代码必须由用户操作触发, 因此放入一个 Listener
    document.querySelector("#myButton").addEventListener("click", async () => {
      // 显示媒体选择框
      const audioDevice = await navigator.mediaDevices.selectAudioOutput();
    
      // 播放音频
      const audio = document.createElement("audio");
      audio.src = "https://example.com/audio.mp3";
      audio.play();
    
      // 指定播放设备
      audio.setSinkId(audioDevice.deviceId);
    });
  • 路径运动动画支持更多函数

    来源: web.dev FireFox 116, Chrome NA, Edge NA, Safari NA

    circle(), ellipse(), rect(), inset(), xywh(), polygon(), ray(), `url()

  • 支持 HTML Element 的画中画

    来源: web.dev FireFox NA, Chrome 116, Edge 116, Safari NA

    画中画曾经只支持装载 Video, 但是现在可以装载 HTML 元素

  • CSS 嵌套语法完成基线支持

    来源: web.dev FireFox 117, Chrome 112, Edge 112, Safari 16.5

工具

Node 模块分类汇总网站

允许分类检索不同领域的 Node 包: https://nodejstoolbox.com/

dnt

将 deno 代码转换为 node: https://deno.com/blog/publish-esm-cjs-module-dnt

Size Limit

一款可用于 GitHub Action, Circle CI... 的大小限制工具, 当用户提交的 JS 打包后大小超限即出发错误: https://github.com/ai/size-limit

实验性内容

Object.groupBy, Map.groupBy()

来源: MDN, MDN Chrome 117, Edge 117, FireFox 119, Safari NA

可以实现一个类似分类汇总的功能

const inventory = [
  { name: "asparagus", type: "vegetables", quantity: 5 },
  { name: "bananas", type: "fruit", quantity: 0 },
  { name: "goat", type: "meat", quantity: 23 },
  { name: "cherries", type: "fruit", quantity: 5 },
  { name: "fish", type: "meat", quantity: 22 },
];
const result = Object.groupBy(inventory, ({ type }) => type);

/* Result is:
{
  vegetables: [
    { name: 'asparagus', type: 'vegetables', quantity: 5 },
  ],
  fruit: [
    { name: "bananas", type: "fruit", quantity: 0 },
    { name: "cherries", type: "fruit", quantity: 5 }
  ],
  meat: [
    { name: "goat", type: "meat", quantity: 23 },
    { name: "fish", type: "meat", quantity: 22 }
  ]
}
*/
const inventory = [
  { name: "asparagus", type: "vegetables", quantity: 9 },
  { name: "bananas", type: "fruit", quantity: 5 },
  { name: "goat", type: "meat", quantity: 23 },
  { name: "cherries", type: "fruit", quantity: 12 },
  { name: "fish", type: "meat", quantity: 22 },
];

const restock = { restock: true };
const sufficient = { restock: false };
const result = Map.groupBy(inventory, ({ quantity }) =>
  quantity < 6 ? restock : sufficient,
);
console.log(result.get(restock));
// [{ name: "bananas", type: "fruit", quantity: 5 }]

动画将支持更多属性

来源: web.dev

文章

  • Understanding React Server Components: RSC 光速入门