接下来判断元素特征,确定是否符合生成条件,对于符合条件的区域,”一视同仁”生成相应区域的颜色块。”一视同仁”即对于符合条件的区域不区分具体元素、不考虑结构层级、不考虑样式,统一根据该区域与视口的绝对距离值生成 div 的颜色块。之所以这样是因为生成的节点是扁平的,体积比较小,同时避免额外的读取样式表、通过抽离样式维持骨架屏的外观,这种统一生成的方式使得骨架屏的节点更可控。基于那上述“走捷径”的想法,该方法生成的骨架屏是由纯 DOM 颜色块拼成的。
- const blocks = [];
- // width,height,top,left 都是算好的百分比
- function drawBlock({width, height, top, left, zIndex = 9999999, background, radius} = {}) {
- const styles = [
- 'position: fixed',
- 'z-index: '+ zIndex,
- 'top: '+ top +'%',
- 'left: '+ left +'%',
- 'width: '+ width +'%',
- 'height: '+ height +'%',
- 'background: '+ background
- ];
- radius && radius != '0px' && styles.push('border-radius: ' + radius);
- // animation && styles.push('animation: ' + animation);
- blocks.push(`<div style="${ styles.join(';') }"></div>`);
- }
绘制颜色块并不难,绘制之前的分析确认才是这个方案真正的核心和难点。比如,对于页面结构比较复杂或者大图片比较多的页面,由图片拼接的区域没有边界,生成的颜色块就会紧挨着,出现不尽如人意的地方。再比如,一个包含很多符合生成条件的小块的 card 块区域,是以 card 块为准还是以里面的小块为准来生成颜色块呢?如果以小块为准,绘制结果可能给人的感觉压根就不是一个 card 块,再加上布局方式和样式的可能性太多,大大增加了不确定因素。而如果以 card 块为准生成颜色块的话还要对 card 块做专门的规则。
& U' ^1 H. q* g" K" [" Y
目前来说,对于页面结构不是特别复杂,不是满屏图片的,不是布局方式特别“飘逸“的场景,该方式已经可以生成比较理想的骨架屏了。而对于那些与预期相差较远的情况,我们提供了两个钩子函数可供微调:
( m* K" K7 _1 `! y! Q/ n2 P
1. init 函数,在开始遍历节点之前执行,适合删除干扰节点等操作。
$ b: _/ l! S: Y4 j! n+ G7 } 2. includeElement(node, draw) 函数,可在遍历到指定节点时,调 用 draw 方法进行自定义绘制。
/ ?3 N6 |4 A2 H 通过以上步骤就能够直接在浏览器中生成骨架屏代码了。
1 T1 e. l" p" S- [- [四、在浏览器里运行/ y7 O ~* F ~5 ~/ \( B: C
由于我们的方案出发点是通过单纯的 DOM 操作,遍历页面上的节点,根据制定的规则生成相应区域的颜色块,最终形成页面的骨架屏,所以核心代码完全可以直接跑在浏览器端;
* A, j2 ?. f5 w* C1 u; m- const createSkeletonHTML = require('draw-page-structure/evalDOM')
- createSkeletonHTML({
- // ...
- background: 'red',
- animation: 'opacity 1s linear infinite;'
- }).then(skeletonHTML => {
- console.log(skeletonHTML)
- }).catch(e => {
- console.error(e)
- })
五、结合 Puppeteer 自动生成骨架屏
6 [" q9 ?$ d9 m0 W4 g" I" h% [2 o 虽然该方式已经可以生成骨架屏代码了,但是还是不够自动化,为了让生成的骨架屏代码自动加载进指定页面。于是,我们开发了一个配套的 CLI 工具。这个工具通过 Puppeteer 运行页面,并把 evalDOM.js 脚本注入页面自动执行,执行的结果是生成的骨架屏代码被插入到应用页面。
/ o! \8 {2 c$ J* J: Q' G2 W5 L. M我们的方案大概思路如下:1 N) x* Z! R% p4 U; I& M6 y" F
2 `1 I& w" X# S
接下来看看如何使用 CLI 工具生成骨架屏,最多只需如下四步:
! K6 P E2 M+ ~& ~2 F1 o5 d
1. 全局安装,npm i draw-page-structure – g
- E# G" T9 V- H2 e! V* t
2. dps init 生成配置文件 dps.config.js
6 U8 O* w% _# n( V' w 3. 修改 dps.config.js 进行相关配置
$ x% S: c8 A7 j' B/ H& L: ? 4. dps start 开始生成骨架屏
" |% ^& H; P( G: O
只需简单几步,然而并没有繁琐的配置:
) o% g! [1 Z% A& `3 y