W3C (World Wide Web Consortium)
IETF (Internet Engineering Task Force)
WHATWG (Web Hypertext Application Technology Working Group)
相关demo 的源码,可以从 juejinBlogsCodes WebApi 获取。
名称 | 功能 |
---|---|
Screen Wake Lock API | 能够防止设备因为闲置而自动调低亮度或锁定屏幕 |
Cookie Store API | 更加便捷获取和设置cookie的信息 |
Compression Stream API | 使用 gzip 或者默认格式压缩和解压缩数据 |
CSS Custom Highlight API | JavaScript 创建范围并使用 CSS 定义样式来设置文档中任意文本范围的样式 |
EyeDropper | 从屏幕上选择颜色 |
Prioritized Task Scheduling API | 对任务优先级进行控制 |
Trusted Types API | 为Web开发者提供了一种锁定DOM(文档对象模型)API中易受攻击部分的方法 |
CSS Font Loading API | 动态加载字体资源的事件和接口 |
Popover API | 内置的弹框能力 |
URL Pattern API | URL匹配器, 类似path-to-regex |
Audio Output Devices API | 音频输出选择能力 |
Device Memory API | 获取内存信息 |
Barcode Detection API | 用于检测图像中的条形码和二维码 |
Screen Wake Lock API 提供了一种方法,使得当应用程序需要保持运行时,能够防止设备因为闲置而自动调低亮度或锁定屏幕。
这对于诸如视频会议、演示文稿、实时游戏、在线教育等需要用户持续关注且不允许屏幕熄灭的应用场景尤其有用。通过使用这个API,即使在没有用户交互的情况下,开发者也能确保屏幕始终保持开启状态。
简简单单30行代码,就能控制和监听 屏幕唤醒锁。
<button onclick="onLockScreen()">锁屏</button>
<button onclick="onUnlockScreen()">释放</button>
<div id="statusElem"></div>
<script>
let wakeLock = null;
async function onLockScreen() {
// create an async function to request a wake lock
try {
wakeLock = await navigator.wakeLock.request("screen");
statusElem.textContent = "唤醒锁已激活";
wakeLock.addEventListener("release", () => {
// the wake lock has been released
statusElem.textContent = "唤醒锁已释放";
});
} catch (err) {
// The Wake Lock request has failed - usually system related, such as battery.
statusElem.textContent = `${err.name}, ${err.message}`;
}
}
async function onUnlockScreen() {
if (!wakeLock) return;
wakeLock.release().then(() => {
wakeLock = null;
});
}
</script>
Compression Stream API 提供了一种 JavaScript API,使用 gzip 或者默认格式压缩和解压缩数据流。 内置的压缩库意味着 JavaScript 应用不再需要包含其它压缩库,这使得应用程序的下载大小更小。
代码嘛,简简单单。
<input type="file" id="file" >
<script>
async function compressAndDownload(filename, content) {
// 创建原始数据流
const stringStream = new ReadableStream({
start(controller) {
controller.enqueue(new TextEncoder().encode(content));
controller.close();
}
});
// 创建压缩流
const compressionStream = new CompressionStream('gzip');
// 将原始数据流连接到压缩流
const compressedStream = stringStream.pipeThrough(compressionStream);
// 创建ArrayBuffer容器接收压缩数据
const chunks = [];
const reader = compressedStream.getReader();
try {
while (true) {
const { done, value } = await reader.read();
if (done) break;
chunks.push(value);
}
} finally {
reader.releaseLock();
}
// 合并压缩数据并创建Blob
const compressedBlob = new Blob(chunks, { type: 'application/gzip' });
// 创建下载链接
const url = URL.createObjectURL(compressedBlob);
const link = document.createElement('a');
link.href = url;
link.download = `${filename}.gz`;
document.body.appendChild(link);
// 触发下载
link.click();
// 清理
setTimeout(() => {
document.body.removeChild(link);
URL.revokeObjectURL(url);
}, 0);
}
file.addEventListener('change', async (event) => {
if(event.target.files.length === 0){
return;
}
const file = event.target.files[0];
const reader = new FileReader();
reader.readAsText(event.target.files[0]);
reader.onload = async () => {
const content = reader.result;
compressAndDownload(file.name, content);
}
})
</script>
CSS 自定义高亮 API 提供了一种方法,可以通过使用 JavaScript 创建范围并使用 CSS 定义样式来设置文档中任意文本范围的样式。
可以去 MDN 在线的示例 进行实操 CSS Custom Highlight API#Result
其逻辑是就是查找所有文本节点,收集匹配内容的 Range
, 最后作为参数构建 HighLight
对象, 需要注意的是其 <b>并未产生新的节点</b>
。
核心逻辑代码如下:
const query = document.getElementById("query");
const article = document.querySelector("article");
// Find all text nodes in the article. We'll search within these text nodes.
const treeWalker = document.createTreeWalker(article, NodeFilter.SHOW_TEXT);
const allTextNodes = [];
let currentNode = treeWalker.nextNode();
while (currentNode) {
allTextNodes.push(currentNode);
currentNode = treeWalker.nextNode();
}
// Listen to the input event to run the search.
query.addEventListener("input", () => {
// If the CSS Custom Highlight API is not supported, display a message and bail-out.
if (!CSS.highlights) {
article.textContent = "CSS Custom Highlight API not supported.";
return;
}
// Clear the HighlightRegistry to remove the previous search results.
CSS.highlights.clear();
// Clean-up the search query and bail-out if if it's empty.
const str = query.value.trim().toLowerCase();
if (!str) {
return;
}
// Iterate over all text nodes and find matches.
const ranges = allTextNodes
.map((el) => {
return { el, text: el.textContent.toLowerCase() };
})
.map(({ text, el }) => {
const indices = [];
let startPos = 0;
while (startPos < text.length) {
const index = text.indexOf(str, startPos);
if (index === -1) break;
indices.push(index);
startPos = index + str.length;
}
// Create a range object for each instance of str we found in the text node.
return indices.map((index) => {
const range = new Range();
range.setStart(el, index);
range.setEnd(el, index + str.length);
return range;
});
});
// Create a Highlight object for the ranges.
const searchResultsHighlight = new Highlight(...ranges.flat());
// Register the Highlight object in the registry.
CSS.highlights.set("search-results", searchResultsHighlight);
});
可以打开并使用它从屏幕上选择颜色。
记住了,是从屏幕上拾取颜色
基于这个做个取色插件,是不是分分钟就搞定呢?
代码,简简单单二三十行:
<button id="start-button">打开拾色器</button>
<img src="https://img.alicdn.com/imgextra/i1/O1CN01CC9kic1ig1r4sAY5d_!!6000000004441-2-tps-880-210.png" />
<div>
颜色是:<span id="result"></span>
</div>
<script>
document.getElementById("start-button").addEventListener("click", () => {
const resultElement = document.getElementById("result");
if (!window.EyeDropper) {
resultElement.textContent = "你的浏览器不支持 EyeDropper API";
return;
}
const eyeDropper = new EyeDropper();
const abortController = new AbortController();
eyeDropper
.open({ signal: abortController.signal })
.then((result) => {
resultElement.textContent = result.sRGBHex;
resultElement.style.backgroundColor = result.sRGBHex;
})
.catch((e) => {
resultElement.textContent = e;
});
});
</script>
提供了一种标准化的方法,用于对属于应用程序的所有任务进行优先级排序。
优先级任务调度API允许开发者为异步任务分配优先级,这些任务按照以下三种优先级顺序执行:
欸,这就给高端玩家无限遐想了,只能一个字表达 太牛了
。
下面一个例子,来看看优先级的输出情况, 可以看到,如你所愿:
<div id="log"></div>
<script>
let log = document.getElementById("log");
function mylog(text) {
log.innerHTML += `${text}<br/>`;
}
// three tasks, in reverse order of priority
scheduler.postTask(() => mylog("background 1"), { priority: "background" });
scheduler.postTask(() => mylog("user-visible 1"), { priority: "user-visible" });
scheduler.postTask(() => mylog("user-blocking 1"), { priority: "user-blocking" });
// three more tasks, in reverse order of priority
scheduler.postTask(() => mylog("background 2"), { priority: "background" });
scheduler.postTask(() => mylog("user-visible 2"), { priority: "user-visible" });
scheduler.postTask(() => mylog("user-blocking 2"), { priority: "user-blocking" });
// Task with default priority: user-visible
scheduler.postTask(() => mylog("user-visible 3 (default)"));
</script>
为Web开发者提供了一种锁定DOM API中不安全部分的方法,目的是防止客户端跨站脚本(Cross-site scripting,XSS)攻击
在下面的例子中,通过 TrustedTypePolicyFactory.createPolicy()
方法创建一个策略,通过 TrustedTypePolicy.createHTML
方法创建一个安全的HTML字符串插入到文档中。
有很大的灵活性,策略是自己可以定义的。
<div id="myDiv"></div>
<script></script>
除此之外,还可以用来创建用来检查 Script
和 ScriptURL
的策略。
const policy = trustedTypes.createPolicy("myPolicy", {
createScriptURL: (s, type, sink) => { //......},
createScript: (s) => { //......}
});
CSS 字体加载 API 为你提供了动态加载字体资源的事件和接口。
以往引入字体主要是靠 css 来实现的, 动态引入字体也可以通过动态添加 link
节点来实现。
@font-face {
2 font-family: 'MyCustomFont';
3 src: url('fonts/mycustomfont.woff2') format('woff2'),
4 url('fonts/mycustomfont.woff') format('woff');
5 font-weight: normal;
6 font-style: normal;
7}
现在呢, 内置了原生AP, 能动态加载字体,而且能控制加载时机,以及加载的状态。
const font = new FontFace("myfont", "url(myfont.woff)", {
style: "italic",
weight: "400",
stretch: "condensed",
});
// 加载字体
font.load().then(()=>{
// 加载完毕
}, (err) => {
// 加载异常
console.error(err);
},);
// 等待到所有的字体都加载完毕
document.fonts.ready.then(() => {
// 使用该字体渲染文字(如:在 canvas 中绘制)
});
音频输出设备API(Audio Output Devices API)赋予了Web应用程序能力,使其能够询问用户希望使用哪个音频输出设备进行声音播放。
欸, 可以选择音频输出设备,还是比较有意思的。协议原文 Audio Output Devices API, 可惜还没有浏览器支持。
document.querySelector("#myButton").addEventListener("click", async () => {
if (!navigator.mediaDevices.selectAudioOutput) {
console.log("selectAudioOutput() not supported or not in secure context.");
return;
}
// Display prompt to select device
const audioDevice = await navigator.mediaDevices.selectAudioOutput();
// Create an audio element and start playing audio on the default device
const audio = document.createElement("audio");
audio.src = "https://example.com/audio.mp3";
audio.play();
// Change the sink to the selected audio output device.
audio.setSinkId(audioDevice.deviceId);
});
传统上,开发人员评估客户端设备性能时,由于无法直接获取设备的RAM大小信息,他们往往需要采取一些经验法则,或是通过设备基准测试,抑或是根据设备制造商、用户代理(User Agent)字符串等其他因素间接推测设备能力。
但现在,有以下两种方法可以直接或间接确定设备的大致RAM量:
navigator.deviceMemory
属性,可以获得设备内存级别的大致信息,如0.5表示小于1GB的RAM,1表示1-2GB,以此类推。Device-Memory
HTTP请求头就包含了设备的内存类别信息。虽然这不是直接在JavaScript中获取,但服务器可以根据这个头信息动态调整响应内容,帮助开发者根据设备RAM大小优化用户体验。const RAM = navigator.deviceMemory; // 8
值是 0.25
, 0.5
, 1
, 2
, 4
,8
之一,所以机器 16G内存,显示的也是8。
用于检测图像中的条形码和二维码。
欸, 这就很有意思,配和 navigator.mediaDevices.getUserMedia
唤起摄像头,定期截图分析,是不是就是一个web版本的扫码能力呢?
if (!("BarcodeDetector" in globalThis)) {
console.log("此浏览器不支持条形码检测器。");
} else {
console.log("条形码检测器是支持的!");
// 创建新检测器
const barcodeDetector = new BarcodeDetector({
formats: ["code_39", "codabar", "ean_13"],
});
barcodeDetector
.detect(imageEl)
.then((barcodes) => {
barcodes.forEach((barcode) => console.log(barcode.rawValue));
})
.catch((err) => {
console.log(err);
});
}