高阶辅助工具表达式,6翻了插图

译者:云的当今世界

https://juejin.cn/post/6987166546502090788

序言

许多机能,只不过内建的Web API已全力支持,

比如说如前所述URLSearchParams或是URL的queryString以获取和聚合

比如说如前所述btoa,atob的base64的标识符和音频

比如说如前所述sendBeacon的统计数据呈报

比如说如前所述Array.from的字符串聚合

比如说如前所述canvas的音频截屏

比如说如前所述URL的UUID聚合

他们用简化的标识符来同时实现相较繁杂的机能,没服务器端库,你也能秀得腾空。

产品目录(方便快捷终端端写作)

localStorage的已采用内部空间

带图带该事件的图形界面通告

原生植物30行标识符同时实现音频截屏

如前所述URLSearchParams以获取queryString的值

如前所述atob和btoa的base64标识符和音频

非正则替换html标识符encode和decode

相较地址转换为绝对地址

如前所述URL或是Crypto.getRandomValues聚合UUID

如前所述Array.from的字符串聚合器

如前所述sendBeacon的安全的统计数据呈报

如前所述toLocaleString千分位

Promise顺序执行

延时执行delay

进度值映射

滑滚动页面到顶部

禁止选择和复制

禁止图片拖拽

自增长ID

localStorage的已采用内部空间

在较新的chrome上测试,localStorage的存储是按照字符个数来算的。包含键和值的。所以在测试标识符中,你把a修改啊,不会影响存储的数量。但是键的长度,会影响存储的数量。

标识符

functiongetLSUsedSpace(){returnObject.keys(localStorage).reduce((total, curKey) =>{if(!localStorage.hasOwnProperty(curKey)) {returntotal;}total += localStorage[curKey].length + curKey.length;returntotal;},0)}复制标识符

示例

localStorage.clear();localStorage.a =“啊”;console.log(getLSUsedSpace());// 2复制标识符

溢出测试

key的值为长度为10的kkkkkkkkkk:输出结果:Max: 5242880 value Length: 5242870当你把key修改长度为1的k:输出结果:Max: 5242880 value Length: 5242879

localStorage.clear();letvalLength =0try{letstr =Array.from({length:5242800}, () =>“啊”).join(“”);valLength = str.length;for(leti =0; i <10000000000000; i++) {str +=“a”valLength +=1;localStorage.setItem(`kkkkkkkkkk`, str);}}catch(err) {console.error(“存储失败”, err);console.log(“Max:”, getLSUsedSpace(),” value Length:”, valLength)}复制标识符高阶辅助工具表达式,6翻了插图1image.png

注意

超过存储上线是会报错的:

高阶辅助工具表达式,6翻了插图2image.png

如何捕获错误,可以参考 MDNtesting\_for\_availability[6]

大致是对Error的错误码和name进行判断

einstanceofDOMException && (// everything except Firefoxe.code ===22||// Firefoxe.code ===1014||// test name field too, because code might not be present// everything except Firefoxe.name ===QuotaExceededError||// Firefoxe.name ===NS_ERROR_DOM_QUOTA_REACHED) &&// acknowledge QuotaExceededError only if theres something already stored(storage && storage.length !==0);复制标识符

参考引用calculating-usage-of-localstorage-space[7]what-is-the-max-size-of-localstorage-values[8]Test of localStorage limits/quota[9]

带图带该事件的图形界面通告

网页也可以以图形界面弹框的形式进行通告,先看个效果图:有头像,有标题,有文本,点击消息通告还能让窗体聚焦,真帅。

高阶辅助工具表达式,6翻了插图3image.png

标识符

functiondoNotify(title, options = {}, events = {}){constnotification =newNotification(title, options);for(leteventinevents) {notification[event] = events[event];}}functionnotify(title, options = {}, events = {}){if(!(“Notification”inwindow)) {returnconsole.error(“This browser does not support desktop notification”);}elseif(Notification.permission ===“granted”) {doNotify(title, options, events);}elseif(Notification.permission !==“denied”) {Notification.requestPermission().then(function(permission){if(permission ===“granted”) {doNotify(title, options, events);}});}}复制标识符

示例tag还可以用去重消息。

notify(“中奖提示”, {icon:“https://sf1-ttcdn-tos.pstatp.com/img/user-avatar/f1a9f122e925aeef5e4534ff7f706729~300×300.image”,body:“恭喜你,掘金签到一等奖”,tag:“prize”}, {onclick(ev) {console.log(ev);ev.target.close();window.focus();}})复制标识符

参考引用notification[10]采用 Web Notifications[11]

原生植物30行标识符同时实现音频截屏

基本原理是把音频画到Canvas里面,然后调用toDataURL或是toBlob,再利用a标签模拟点击,download属性指定名字。

看一下效果:

高阶辅助工具表达式,6翻了插图4标识符

functioncaptureVideo(videoEl){letcanvasEl;letdataUrl;try{constcps =window.getComputedStyle(videoEl);constwidth = +cps.getPropertyValue(“width”).replace(“px”,“”);constheight = +cps.getPropertyValue(“height”).replace(“px”,“”);canvasEl =document.createElement(“canvas”);canvasEl.style.cssText =`position:fixed;left:-9999px`;canvasEl.height = height;canvasEl.width = width;document.body.appendChild(canvasEl);constctx = canvasEl.getContext(“2d”);ctx.drawImage(videoEl,0,0, width, height);// const image = canvas.toDataURL(“image/png”);dataUrl = canvasEl.toDataURL();document.body.removeChild(canvasEl);canvasEl =null;returndataUrl;}finally{if(canvasEl) {document.body.removeChild(canvasEl);}if(dataUrl) {returndataUrl;}}}复制标识符

示例注意添加crossorigin=”anonymous”,不然转为图片会失败。

“videoEL”controls autoplay crossorigin=“anonymous”src=“https://api.dogecloud.com/player/get.mp4?vcode=5ac682e6f8231991&userId=17&ext=.mp4”width=“500”></video>function download(url) {const aEl = document.createElement(“a”);aEl.href = url;aEl.download = “音频.png”;aEl.click();}function doCaptureVideo() {const url = captureVideo(videoEL);download(url);}doCaptureVideo()复制标识符

如前所述URLSearchParams或URL以获取queryString的值

常用的方式是采用正则或是split方法,只不过不然,URLSearchParams和URL都能很好的同时实现机能。

标识符

consturlSP =newURLSearchParams(location.search);functiongetQueryString(key){returnurlSP.get(key)}consturlObj =newURL(location.href);functiongetQueryString(key){returnurlObj.searchParams.get(key)}复制标识符

示例

测试地址: /index.html?pid=10constlog =console.log;getQueryStringlog(“pid”, getQueryString(“pid”));// pid 10log(“cid”, getQueryString(“cid”));// cid null复制标识符

参考引用MDN文献:URLSearchParams-MDN[12]CanIUse兼容性:URLSearchParams: 95.63\%[13]Polyfill:url-search-params-polyfill[14]

如前所述atob和btoa的base64标识符和音频

浏览器内建了base64标识符和音频的能力,服务器端库,不需要的。

标识符

functionutf8_to_b64(str){returnwindow.btoa(unescape(encodeURIComponent( str )));}functionb64_to_utf8(str){returndecodeURIComponent(escape(window.atob( str )));}复制标识符

示例

utf8_to_b64(✓ à la mode);// “4pyTIMOgIGxhIG1vZGU=”b64_to_utf8(4pyTIMOgIGxhIG1vZGU=);// “✓ à la mode”复制标识符

参考引用MDN文献:atob[15],btoa[16]CanIUse兼容性:btoa 99.68\%[17]Polyfill:MDN Polyfill[18]Base64[19]

非正则替换的html标识符encode和decode

常规的方式是采用正则替换,这里是另外一种思路。

标识符

functionhtmlencode(s){vardiv =document.createElement(div);div.appendChild(document.createTextNode(s));varresult = div.innerHTML;div =null;returnresult;}functionhtmldecode(s){vardiv =document.createElement(div);div.innerHTML = s;varresult = div.innerText || div.textContent;div =null;returnresult;}复制标识符

示例

htmlencode(
3>5 & 666
); // <div>3>5 & 666</div>htmldecode(“<div>3>5 & 666</div>”) // 
3>5 & 666
复制标识符

相较地址转换为绝对地址

如前所述当前页面的相较地址转换为绝对地址。

标识符

functionrealativeToAbs(href){letaEl =document.createElement(“a”);aEl.href = href;constresult = aEl.href;aEl =null;returnresult;}复制标识符

示例

console.log(“realativeToAbs”, realativeToAbs(“../a/b/b/index.html”));// realativeToAbs http://127.0.0.1:5500/a/b/b/index.html复制标识符

如前所述URL或是Crypto.getRandomValues聚合UUID

如前所述URL.createObjectURL[20]或是Crypto.getRandomValues[21]

URL.createObjectURL 产生的地址为blob:https://developer.mozilla.org/cb48b940-c625-400a-a393-176c3635020b, 其后部分是一个UUID

标识符方式一:

functiongenUUID(){consturl = URL.createObjectURL(newBlob([]));// const uuid = url.split(“/”).pop();constuuid = url.substring(url.lastIndexOf(/)+1);URL.revokeObjectURL(url);returnuuid;}genUUID()// cd205467-0120-47b0-9444-894736d873c7复制标识符

方式二:

functionuuidv4(){return([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g, c =>(c ^ crypto.getRandomValues(newUint8Array(1))[0] &15>> c /4).toString(16)}uuidv4()// 38aa1602-ba78-4368-9235-d8703cdb6037复制标识符

参考引用generating-uuids-at-scale-on-the-web-2877f529d2a2[22]collisions-when-generating-uuids-in-javascript[23]

如前所述Array.from的字符串聚合器

造有序统计数据,无序统计数据,等等。

标识符

constrange =(start, stop, step) =>Array.from({length: (stop – start) / step +1},(_, i) => start + (i * step));复制标识符

示例

range(0,4,1);// [0, 1, 2, 3, 4]range(0,9,3);// [0, 3, 6, 9]range(0,8,2.5)// [0, 2.5, 5, 7.5]复制标识符

如前所述sendBeacon的安全的统计数据呈报

sendBeacon[24]异步地向服务器发送统计数据,同时不会延迟页面的卸载或影响下一导航的载入性能。

functionreport(url, data){if(typeofnavigator.sendBeacon !==“function”) {returnconsole.error(“sendBeacon不被全力支持”);}navigator.sendBeacon(url, data);}复制标识符

示例

window.addEventListener(unload, logData,false);functionlogData(){report(“/log”,“被卸载了”);}复制标识符

如前所述toLocaleString千分位

正则?遍历?不需要的。内建表达式解决。当然,如果是超大的数,可能是会有问题的。

标识符

functionformatMoney(num){return(+num).toLocaleString(“en-US”);}复制标识符

示例

console.log(formatMoney(123456789));  // 123,456,789console.log(formatMoney(6781)) // 6,781console.log(formatMoney(5)) // 5超大的数formatMoney(19999999933333333333333) // 19,999,999,933,333,333,000,000复制标识符

Promise顺序执行

让Promise顺序的执行,并全力支持初始化参数和结果作为参数传递。

标识符

functionrunPromises(promiseCreators, initData){returnpromiseCreators.reduce((promise, next) =>promise.then((data) =>next(data)),Promise.resolve(initData));}复制标识符

示例

varpromise1 =function(data =0){returnnewPromise(resolve=>{resolve(data +1000);});}varpromise2 =function(data){returnnewPromise(resolve=>{resolve(data-500);});}runPromises([promise1, promise2],1).then(res=>console.log(res));复制标识符

延时执行delay

延时执行某表达式,且只会执行一次。

标识符

functiondelay(fn = () =>{ }, delay =5000, context =null) {letticket =null;letrunned =false;return{run(…args) {returnnewPromise((resolve, reject) =>{if(runned ===true) {return;}runned =true;ticket = setTimeout(async() => {try{constres =awaitfn.apply(context, args);resolve(res);}catch(err) {reject(err)}}, delay)})},cancel:()=>{clearTimeout(ticket);}}}复制标识符

示例

delay(function(){console.log(“你们好”);}).run();const{ run, cancel } = delay(function(name){console.log(“你好:”, name);});run(“吉他”);run(“吉他”);// 你们好// 你好: 吉他复制标识符

进度值映射

进度映射,比较只有 10%的进度,确要显示50%的进度的场景。

标识符

functionadjustProgress(progress:number, mapping: { real:number; target:number}[] = []){if(progress <0) {return0;}if(!mapping || mapping.length <=0) {returnprogress;}// 第一个constf = mapping[0];if(progress <= f.real) {returnprogress * (f.target / f.real);}// 最后一个constl = mapping[mapping.length –1];if(progress >= l.target) {returnl.target;}constcurIndex = mapping.findIndex(m=>m.real >= progress);if(!curIndex) {returnprogress;}constcur = mapping[curIndex];constpre = mapping[curIndex –1];//     原基数     +   实际进度/最大实际进度 * 期望间距returnpre.target + (progress – pre.real) / (cur.real – pre.real) * (cur.target – pre.target);}复制标识符

示例

constmapping = [{real:0,target:0,}, {real:30,target:50}, {real:60,target:80}, {real:100,target:100}];console.log(“15”, adjustProgress(15, mapping));// 15 25console.log(“25”, adjustProgress(25, mapping));// 25 41.66666666666667console.log(“50”, adjustProgress(50, mapping));// 50 70console.log(“60”, adjustProgress(60, mapping));// 60 80console.log(“100”, adjustProgress(100, mapping));// 100 100复制标识符

滑滚动页面到顶部

标识符

PC端滚动的根元素是document.documentElement,终端端滚动的的根元素是document.body,有一个更好的属性document.scrollingElement能自己识别文档的滚动元素, 其在PC端等于document.documentElement, 其在终端端等于document.body

// smooth 选项在Safari上全力支持不好functionscrollToTop(){window.scrollTo({left: 0,top: 0,behavior:smooth})}function scrollToTop() {let scrollTop = document.documentElement.scrollTop || document.body.scrollTop;if (scrollTop > 0) {window.requestAnimationFrame(scrollToTop);window.scrollTo(0, scrollTop – scrollTop / 8);}};复制标识符

禁止选择和复制

标识符

[contextmenu,selectstart,copy].forEach(function(ev){document.addEventListener(ev,function(ev){ev.preventDefault();ev.returnValue =false;})});复制标识符

当然也有CSS方案

body{-moz-user-select: none;-webkit-user-select: none;-ms-user-select: none;-khtml-user-select: none;user-select: none;}复制标识符

禁止图片拖拽

标识符

[dragstart].forEach(function(ev){document.addEventListener(ev,function(ev){ev.preventDefault();ev.returnValue =false;})});复制标识符

自增长ID

自己生产自增长的ID值,当然可以更繁杂一些。

标识符

letid = 0;functiongetId() {returnid++;}复制标识符

示例

console.log(getId()); // 1console.log(getId()); // 2复制标识符

写在后面

写作不易,你的一赞一在看,是我前行的大动力。

往期干货

26个经典微信小程序+35套微信小程序源码+微信小程序合集源码下载(免费)

干货~~~2021新前端学习音频~~速度领取

前端书籍-前端290本高清pdf电子书打包下载

高阶辅助工具表达式,6翻了插图5

点赞和在看是大的全力支持❤️

作者 nasiapp

在线客服
官方客服
我们将24小时内回复。
12:01
您好,有任何疑问请与我们联系!

选择聊天工具: