最简单的骨架屏实现方式,适用于VUE项目,小程序项目,uniapp项目。
1、VUE项目 skeleton.vue插件<template><div><div class="wrap":style="{'width':systemInfo.width+'px','height':systemInfo.height+'px', 'background-color':bgcolor}"><div v-for="(item,index)
·
1、VUE项目 skeleton.vue 插件
<template>
<div>
<div class="wrap"
:style="{'width':systemInfo.width+'px','height':systemInfo.height+'px', 'background-color':bgcolor}">
<div v-for="(item,index) in skeletonRectLists"
:index='index'
:key='index'
class="chiaroscuro"
:style="{'width':item.width+'px','height':item.height+'px','background-color':'rgba(233, 2, 233,1)','position':'absolute','left':item.left+'px','top':item.top+'px'}">
</div>
<div v-for="(item,index) in skeletonCircleLists"
:index='index'
:key="'info2-'+index"
class="chiaroscuro"
:style="{'width':item.width+'px','height':item.height+'px','background-color':'rgba(233, , 233,1)','border-radius':item.width+'px','position':'absolute','left':item.left+'px','top':item.top+'px'}">
</div>
</div>
</div>
</template>
<script>
export default {
props: {
bgcolor: { type: String, value: '#FFF' },
selector: { type: String, value: 'skeleton' },
},
data() {
return {
systemInfo: {},
skeletonRectLists: [],
skeletonCircleLists: [],
};
},
components: {},
mounted: function() {
//默认的首屏宽高,防止内容闪现
this.systemInfo = {
width: window.innerWidth,
height: window.innerHeight,
};
var dom = document.querySelectorAll(`.$ {
this.selector
}`);
//this.systemInfo.height = dom[0].clientHeight + dom[0].offsetTop || 0;
//绘制矩形
this.rectHandle();
//绘制圆形
this.radiusHandle();
},
methods: {
//绘制距形
rectHandle: function() {
let dom = document.querySelectorAll(`.$ {
this.selector
} - rect`);
for (var i = 0; i < dom.length; i++) {
this.skeletonRectLists.push(dom[i].getBoundingClientRect());
}
},
//绘制圆形
radiusHandle: function() {
let dom = document.querySelectorAll(`.$ {
this.selector
} - radius`);
for (var i = 0; i < dom.length; i++) {
this.skeletonCircleLists.push(dom[i].getBoundingClientRect())
}
},
},
};
</script>
<style scoped>
.wrap {
position: absolute;
left: 0;
top: 0;
z-index: 9998;
overflow: hidden;
}
.chiaroscuro {
animation-duration: 1s;
animation-fill-mode: forwards;
animation-iteration-count: infinite;
animation-name: placeHolderShimmer;
animation-timing-function: linear;
background: #f6f7f8;
background: linear-gradient(to right, #eeeeee 8%, #dddddd 18%, #eeeeee 33%);
background-size: 800px 104px;
height: 40px;
position: relative;
}
@keyframes placeHolderShimmer{
0% {
background-position: -468px 0
}
100% {
background-position: 468px 0
}
}
</style>
VUE项目调用
<template>
<div class="content ">
<skeleton selector="skeleton" bgcolor="#FFF" v-if="showSkeleton"></skeleton>
<div class="skeleton">
<img class="logo skeleton-rect" src="/static/logo.png">
<div class="text-area skeleton-radius">
<div class="title">{{ title }}</div>
</div>
</div>
</div>
</template>
<script>
import skeleton from '@/pages/index/skeleton.vue'
export default {
data() {
return {
showSkeleton:
true,
title: 'Hello',
}
},
components: {
'skeleton': skeleton
},
created() {
this.reloadData();
},
methods: {
reloadData() {
setTimeout(() = >{
this.showSkeleton = false
},
2000)
},
}
}
</script>
2、别人写的 uniapp 插件
<template>
<div>
<div class="wrap"
:style="{'width':systemInfo.width+'px','height':systemInfo.height+'px', 'background-color':bgcolor}">
<div v-for="(item,index) in skeletonRectLists"
:index='index'
:key='index'
class="chiaroscuro"
:style="{'width':item.width+'px','height':item.height+'px','background-color':'rgba(233, 2, 233,1)','position':'absolute','left':item.left+'px','top':item.top+'px'}">
</div>
<div v-for="(item,index) in skeletonCircleLists"
:index='index'
:key="'info2-'+index"
class="chiaroscuro"
:style="{'width':item.width+'px','height':item.height+'px','background-color':'rgba(233, , 233,1)','border-radius':item.width+'px','position':'absolute','left':item.left+'px','top':item.top+'px'}">
</div>
</div>
</div>
</template>
<script>
/* eslint-disable */
export default {
props: {
bgcolor: { type: String, value: '#FFF' },
selector: { type: String, value: 'skeleton' },
},
data() {
return {
systemInfo: {},
skeletonRectLists: [],
skeletonCircleLists: [],
};
},
components: {},
mounted: function() {
//默认的首屏宽高,防止内容闪现
const systemInfo = uni.getSystemInfoSync();
(this.systemInfo = {
width: systemInfo.windowWidth,
height: systemInfo.windowHeight,
});
const that = this;
//绘制背景
uni
.createSelectorQuery()
.selectAll(`.${this.selector}`)
.boundingClientRect()
.exec(function(res) {
console.log(res);
that.systemInfo.height = res[0][0].height + res[0][0].top || 0;
});
//绘制矩形
this.rectHandle();
//绘制圆形
this.radiusHandle();
},
methods: {
rectHandle: function() {
const that = this;
//绘制不带样式的节点
uni
.createSelectorQuery()
.selectAll(`.${this.selector}-rect`)
.boundingClientRect()
.exec(function(res) {
that.skeletonRectLists = res[0];
});
},
radiusHandle: function() {
const that = this;
uni
.createSelectorQuery()
.selectAll(`.${this.selector}-radius`)
.boundingClientRect()
.exec(function(res) {
console.log(res[0].length);
that.skeletonCircleLists = res[0];
});
},
},
};
/* eslint-enable */
</script>
<style scoped>
.wrap {
position: absolute;
left: 0;
top: 0;
z-index: 9998;
overflow: hidden;
}
.chiaroscuro {
animation-duration: 1s;
animation-fill-mode: forwards;
animation-iteration-count: infinite;
animation-name: placeHolderShimmer;
animation-timing-function: linear;
background: #f6f7f8;
background: linear-gradient(to right, #eeeeee 8%, #dddddd 18%, #eeeeee 33%);
background-size: 800px 104px;
height: 40px;
position: relative;
}
@keyframes placeHolderShimmer{
0% {
background-position: -468px 0
}
100% {
background-position: 468px 0
}
}
</style>
调用和VUE差不多
注意:显示距形:则在样式上添加 skeleton-rect, 显示圆形 :skeleton-radius , 如果没有添加这两个样式,则是一片空白
实现原理:根据原有的DIV 宽和高以及left和top 来绘制一个空白div。循环生成多个div 再给DIV加上样式动画。设置时间 多少秒后消失。
更多推荐
已为社区贡献5条内容
所有评论(0)