【小书签】一键骨架屏(Skeleton Screen)

原始页面效果如下(点击查看大图):

用小书签转换为骨架屏效果之后(点击查看大图):

一个用来快速将当前页面转换为骨架屏效果的小书签,别问我有什么用,我也不知道,我就是玩儿。

需要注意转换后的效果,无法回退,只能刷新页面重新载入。输入框内的内容也会被转换,所以在输入框里有数据的时候,使用此功能会导致数据丢失。

如果页面使用了懒加载功能,可能导致转换不全,但是此书签可以反复使用。

目前只完成了初步的功能,细节有待完善,如果你遇到问题,可以在这里反馈。如果你觉得好用,记得支持我。

老鼠爱发电

将如下代码当成网址,保存为书签即可。

我对小书签进行更新时,无法通知原有用户,所以,如果对此有需求,记得经常过来关注一下更新进度

  • 对文字颜色增加了一个减淡操作,现在的效果不会像上面截图那么辣眼睛了(稍微柔和一丢丢
  • 文字转换为色块之后,将高度降低为原文字的 60%
  • 将占位图片转为本地生成,解决一些情况下无法请求占位图片的状况

Update:2021-01-12 13:06:28

javascript:(()=>{const VERSION="2021-01-12 13:06:28",midColor=rgb=>rgb.replace(/\d+/g,num=>(num=+num)>=128?128+(num-128)/2:128-(128-num)/2),textNodes=[],copyAtts=(newEl,el)=>{const atts=["id","class","style"];for(const att of atts)el.getAttribute(att)&&newEl.setAttribute(att,el.getAttribute(att))},getPic=(width,height,text)=>{const canvas=document.createElement("canvas"),ctx=canvas.getContext("2d");canvas.width=width,canvas.height=height,ctx.fillStyle="#F3F3F3",ctx.fillRect(0,0,width,height);const strArr=text.split(/\n/g),maxLength=Math.max.apply(null,strArr.map(s=>s.length));if(maxLength){const fontSize=Math.min(width/maxLength,height/strArr.length);ctx.font="Bold "+fontSize+"px Consolas",ctx.textAlign="center",ctx.fillStyle="#999";const x=width/2,y=(height-fontSize*strArr.length)/2+fontSize;strArr.forEach((str,i)=>{ctx.fillText(str,x,y+i*fontSize)})}return canvas.toDataURL("image/png")};document.body.querySelectorAll("*").forEach(el=>{for(e of el.childNodes)e.nodeType==Node.TEXT_NODE&&textNodes.push(e);const elStyle=window.getComputedStyle(el);if("none"!==elStyle.backgroundImage&&/^url\(.*\)$/.test(elStyle.backgroundImage)){const img=document.createElement("img");img.src=elStyle.backgroundImage.replace(/^url\("(.*)"\)$/,"$1"),img.onload=()=>{el.style.backgroundImage='url("'+getPic(img.width,img.height,img.width>30&&img.height>30?"background\n"+img.width+"x"+img.height:"")+'")'}}if(-1!==["IMG","SVG","CANVAS","VIDEO"].indexOf(el.tagName)){const width=(+elStyle.width.replace(/px$/,"")).toFixed(),height=(+elStyle.height.replace(/px$/,"")).toFixed();if("IMG"===el.tagName)return el.src=getPic(el.naturalWidth,el.naturalHeight,width+"x"+height),void(el.srcset.length&&(el.srcset=el.src));const newEl=document.createElement("img");return newEl.src=getPic(width,height,el.tagName+"\n"+width+"x"+height),copyAtts(newEl,el),void el.parentNode.replaceChild(newEl,el)}if("INPUT"===el.tagName||"TEXTAREA"===el.tagName)return el.value=el.value.replace(/./g,"▮"),void(el.placeholder=el.placeholder.replace(/./g,"▮"))}),document.title=document.title.replace(/./g,"▮"),textNodes.forEach(textEl=>{if(/^[\s\n]*$/g.test(textEl.textContent))return;const elStyle=window.getComputedStyle(textEl.parentNode);if(!elStyle.lineHeight||!elStyle.fontSize)return;const newTextNode=document.createElement("span"),color="rgba(0,0,0,0) !important",bgColor=elStyle.color,lineHeight=+elStyle.lineHeight.replace(/px$/,""),fontSize=+elStyle.fontSize.replace(/px$/,""),blankHeight=(100*(lineHeight-.8*fontSize)/2/lineHeight).toFixed(),bgGradient="linear-gradient(to bottom, transparent 20%, "+midColor(bgColor)+" 20% 80%, transparent 80%) !important";newTextNode.style="color: "+color+"; background: "+bgGradient+";",newTextNode.innerHTML=textEl.textContent,textEl.parentNode.replaceChild(newTextNode,textEl)})})();
3 个赞

想法:对某个网站截屏做封面时不想打码信息又想让别人认出来这是啥

  1. 头一次知道这叫骨架屏,我叫它网页未完全加载时的懒加载/占位图形
  2. 有的地方是不是显示错位了,或者说因为长度不一致而显得丑

我昨天才知道的具体名字,觉得可以这样实现,但其实有点类似于逆向操作,就像你说的,他大多数是在网页未加载完全的时候用来占位的。

错位问题基本已经解决掉了。但有一些图形和媒体元素是通过替换元素来实现的效果,这样难免会出问题。

这才是比较头疼的,文字本身毕竟不是填充,背景颜色显示出来的比较多,变成矩形之后,背景就被大部分做到了,所以效果会很奇怪。

但这个问题不好解决,虽然可以考虑将文字矩形的高度给变低一点,但复杂度增加的有一点高,又是整个页面大量的元素,所以比较犹豫。

然后文字的颜色也是个问题,因为文字的颜色和背景颜色是关联的,但是对于一个元素实际所呈现的背景颜色很难计算,所以这里也是一个难以解决的问题。

长度不一致显示的丑主要是有些元素是居中对齐的,比如图片里回复、浏览、活动的数字

降低文字方块的高度可以极大的缓解这种感觉,现在文字方块儿太凸显了。我想想怎么去处理这个问题吧

骨架这个描述是真的形象了,饱和度低一点好多了

这个真的不错