随着技术的不断革新,现代浏览器提供了很多高级的功能用来满足开发者的需要。这些新的API
在程序员的”红宝书“里未必能见到它们的身影,不过仍需要提前了解以备不时之需。
Beacon API
Beacon API
可以向服务器发送少量的数据以实现统计等目的。同时它的性能比我们平常使用Ajax
发送请求更好。当你需要发送数据但不要求有返回值的时候,都可以使用这个API
。所有的数据都是在空闲时间发送的。
比如下面这个例子:
const beaconURL = "https://example.com"
function sendEvent(strEvent) {
// 由于这个API还处于实验阶段,为了照顾低版本浏览器需要进行功能检测处理。
if (navigator.sendBeacon) {
navigator.sendBeacon();
}
}
window.addEventListener('load',function(e) {
sendEvent("loadEvent");
document.getElementById("btn1").addEventListener("click",function(){
sendEvent("Button 1 click");
});
});
可以通过在事件监听函数中触发发送请求事件达到统计的目的。
InterpObserver API
InterpObserver API
是用来监视某个元素是否进入了浏览器的可视区域。因此,可以利用这个特性达到延迟加载的目的:
window.addEventListener("load", function () {
const observer = new InterpObserver(function (entries) {
console.log(entries);
}, {
"threshold": [0, 0.5, 1.0]
});
});
其中threshold
表示触发回调函数的临界值。比如0.5
表示在可视区域内能看到一半元素的时候触发一次。因此上面的例子中[0, 0.5, 1.0]
总共会在元素刚进入可视区域、进入一半和完全进入这三个阶段都触发一次回调函数。
你可能经常在使用某个网页的时候在浏览器上看到提示框,现在利用Notification
接口我们自己也能够实现这样的功能。
主要分为两步:
window.addEventListener("load", () => {
document.getElementById("btnRequest").addEventListener("click",()=>{
Notification.requestPermission().then(() => {
if(Notification.permission==="granted") {
// 发送通知
sendNotifaction("欢迎关注前端人")
}
})
})
})
function sendNotification(text) {
let notification = new Notification('页面标题', {
icon: "../image.png",
body: text,
});
notification.onclick = function(evt) {
parent.focus();
window.focus();
evt.target.close();
};
let timeObj=setTimeout(()=>{
notification.close.bind(notification);
clearTimeout(timeObj)
}, 5000);
}
CacheStorage API
进行缓存数据CacheStorageAPI
是官方提供的另外一种用来存储数据的接口,具体定义可以参考MDN上面:
CacheStorage
接口表示 Cache
对象的存储。它提供了一个 ServiceWorker
、其它类型worker
或者window
范围内可以访问到的所有命名cache
的主目录(它并不是一定要和service workers
一起使用,即使它是在service workers
规范中定义的),并维护一份字符串名称到相应 Cache
对象的映射。
这个API
使用起来也比较简单:
function getJSONData(url) {
if ('cache' in window) {
window.caches.open('my-data-cache').then(function(cache) {
if (result === undefined) {
fetch(url).then(function (result) {
let clonedresp = result.clone();
// 将数据存储到浏览器中去:
cache.put(url, result);
result.text().then(function(data) {
console.log(data);
});
});
}
})
}
}
IndexedDB
是异步的,可以让web
保持响应,而不是像localStorage
一样阻塞页面。同时它还可以存储多种类型数据,很容易分为多个独立的实例进行存储。
const instance1, instance2;
document.getElementById("btnMulti").addEventListener("click", function () {
instance1 = localforage.createInstance({
"name": "instance1"
});
instance2 = localforage.createInstance({
"name": "instance2"
});
});
document.getElementById("btnStore").addEventListener("click", function () {
instance1.setItem("key1", "value1");
instance2.setItem("key1", "value2");
});
不过使用IndexedDB
是复杂的,可以借助第三方库localForage
来简化代码操作:
npm install localforage
安装完成后,可以在代码里这样应用:
localforage.getItem("test").then(value => {
console.log(value);
}).catch(err => {
console.log(err)
});
localforage.setItem("test", "some value").then(value => {
console.log(value);
}).catch(err => {
console.log(err);
});
检测浏览器内存的功能可能不太常用,但如果你是开发移动端页面,对于内存比较小的设备来说,检测功能有时候就能够派上用场:
window.addEventListener("load", () => {
if (navigator.storage && navigator.storage.estimate) {
navigator.storage.estimate().then(estimate => {
console.log("The remaining space: " + estimate.quota);
console.log("Space used:" + estimate.usage);
});
}
// 检测应用数据是否是持久化的
if (navigator.storage && navigator.storage.persisted) {
navigator.storage.persisted().then(persisted => {
console.log("Storage persistence: " + persisted);
});
}
if (navigator.deviceMemory) {
console.log("The device memory is: " + navigator.deviceMemory);
}
})
最终执行结果如下:
The device memory is: 8
Storage persistence: false
VM72:3 The remaining space: 244355911680
VM72:4 Space used:0
有时候我们要根据网络状态来采取不同的业务处理,如离线加载等,这就需要能够检测到浏览器中网络连接情况。要实现这个需求,可以借助window.navigator
对象:
const isOnline = window.navigator.onLine;
if (window.navigator.conneciton) {
const connection = navigator.connection;
console.log(connection);
}
这是个只读对象,其中提供了很多很浏览器特性相关的属性,利用connection
这个属性就可以检测到浏览器连接状态。
downlink: 1.05
effectiveType: "3g"
onchange: null
rtt: 300
saveData: false
而借助onLine
属性我们就可以知道此时网络是否可用。
开发视频页面的时候,经常需要和全屏事件打交道,此时你可以借助浏览器自身的这个特性对其操作:
function enterFullscreen(ele) {
if (ele.requestFullscreen) {
ele.requestFullscreen();
}
}
function exitFullscreen(ele) {
if (ele.requestFullscreen) {
ele.exitFullscreen();
}
}
:full-screen
样式方面,和操作滚动条样式类似,对应的浏览器也提供了:full-screen
这样的伪元素选择器:
:full-screen button {
background: red;
}
:-webkit-full-screen button {
background: red;
}
:-moz-full-screen button {
background: red;
}
:-ms-fullscreen button {
backgorund: red;
}
CSS Houdini
是现代CSS
提供的一个高级API
,由于开放了底层接口,我们借助它实现一些更加高级的特性。
比如接下来这个例子,我将实现一个自定义的属性samplepainter
。
新建一个叫做csspaint_start.js
的文件:
if (typeof registerPaint !== "undefined") {
class SampleCSSPaint {
static get inputProperties() {
return ['--cross-thickness', '--cross-color']
}
paint(ctx, size, props) {
let width = props.get('--cross-thickness');
let color = props.get('--cross-color').toString();
ctx.lineWidth = width;
ctx.strokeStyle = color;
ctx.beginPath();
ctx.moveTo(0,0);
ctx.lineTo(size.width, size.height);
ctx.stroke();
ctx.beginPath();
ctx.stroke();
}
}
registerPaint('samplepainter', SampleCSSPaint);
}
然后将我们刚才写好的模块注册到启动脚本main.js
中去:
window.addEventListener("load", function () {
// 检测浏览器是否支持paintWorklet
if ('paintWorklet' in CSS) {
console.log("paintWorklet supported")
CSS.paintWorklet.addModule("csspaint_start.js");
} else {
console.log("paintWorklet not supported")
}
});
接着我们就可以在css
中使用自定义的属性进行操作了:
#demo {
background-image: paint(samplepainter);
--cross-thickness: 2;
--cross-color: red;
}
1. JavaScript 重温系列(22篇全)
2. ECMAScript 重温系列(10篇全)
3. JavaScript设计模式 重温系列(9篇全)
4. 正则 / 框架 / 算法等 重温系列(16篇全)
5. Webpack4 入门(上)|| Webpack4 入门(下)
6. MobX 入门(上) || MobX 入门(下)
7. 70+篇原创系列汇总
回复“加群”与大佬们一起交流学习~
点击“阅读原文”查看70+篇原创文章
点这,与大家一起分享本文吧~