Dear,大家好,我是“前端小鑫同学”,😇长期从事前端开发,安卓开发,热衷技术,在编程路上越走越远~
承接上篇【dart-skeleton】自动生成骨架屏项目内容,这一篇主要来说一下第一块内容脚本篇,也是我们整个项目的关键部分。
eval
进行包装,由于各种编译场景均不太允许直接使用eval
函数,所以我们进行了重新赋值的处理,编程了_eval
。对象类型进行反序列化为对象,字符串则直接接受即可。由于页面各式各样,不合理的布局将会造成解析的结果非常糟糕,我们可以通过指定元素选项来进行过滤,由于页面也会存在一些被隐藏或透明的元素我们也将跳过。
display属性为none的节点;
visibility属性为hidden的节点;
opacity属性为0的节点。
我们在入口参数提供了一个includeElement
函数,这个函数可以接收一个dom节点
和一个绘制函数,当接收到dom节点
后通过对选项进行筛选反返回为false
即可跳过对应元素。
const isCustomSkip = typeof this.includeElement === "function" && this.includeElement(node, this.drawBlock) == false;
当元素设置了background-image
属性时,如果解析到内容包含url
地址则需要绘制;
当遍历到该元素的子元素包含文本类型的节点且节点内容不为空时需要绘制;
遍历当前的元素为文本类型且节点内容不为空时需要绘制;
当元素在我们的预设列表中存在时需要绘制。
注:
以上条件满足一项即需要绘制。
当我们设置需要绘制头部的时候,如果头部的高度会遮挡一部分元素,那么这部分元素可跳过不绘制。
drawBlock({
width,
height,
top,
left,
zIndex = 999,
background = this.background,
radius,
subClas = false,
}: DrawBlock) {
const styles = [`height:${height}%`];
if (!subClas) {
styles.push(`top:${top}%`, `left:${left}%`, `width:${width}%`);
}
if (classProps.zIndex !== zIndex) {
styles.push(`z-index:${zIndex}`);
}
if (classProps.background !== background) {
styles.push(`background:${background}`);
}
radius && radius != "0px" && styles.push(`border-radius:${radius}`);
this.blocks.push(
`<div class="_${subClas ? " __" : ""}" style="${styles.join(";")}"></div>`
);
}
这一块相对简单很多,就是一个dom操作将我们处理得到的字符串拆入到目标页面的body节点中:
const { body } = document;
const blocksHTML = this.blocks.join("");
const div = document.createElement("div");
div.innerHTML = blocksHTML;
body.appendChild(div);
说明: 此项目是在dps项目的基础上重写的一个Ts版本,目的是学习思路方便后续改造。