如何实现骨架屏效果?

今天我们来用原生js实现一个骨架屏的效果,效果如下:

首先思考如何实现

思考实现方式

骨架屏的原理是在数据没加载出来的时候,使用滚动的背景颜色去替代,等到加载完毕后则显示对应内容

那么我们的核心就是实现一个.skeleton的样式,当这个样式出现的时候,就通过animation去开启一个背景色无限滚动的动画,数据加载完毕后则将这个类名去除即可

思路还是比较简单的,我们先搭建一个整体结构,将数据都写死看看效果单的,我们先搭建一个整体结构,将数据都写死看看效果e单的,我们先搭建一个整体结构,将数据都写死看看效果单的,我们先搭建一个整体结构,将数据都写死看看效果e先

静态结构

<

I love coding!

Talk is cheap. Show me the code.

PlasticineAug 13, 2022

再写一些基础样式

img {height: 100%;width: 100%;object-fit: cover;
}

.card {width: 350px;border-radius: 10px;background-color: white;overflow: hidden;box-shadow: 5px 5px 10px 10px rgba(255, 255, 255, 0.2);
}

.card header {height: 200px;
}

.card main {padding: 30px;
}

.card main h3 {margin: 0;
}

.card main p {color: gray;
}

.author {display: flex;align-items: center;gap: 10px;
}

.author .author-avatar {height: 40px;width: 40px;border-radius: 50%;overflow: hidden;
}

.author .author-info {display: flex;flex-direction: column;gap: 5px;width: 100px;
}

.author .author-info small {color: gray;
} 

现在的效果如下:

如何实现骨架屏效果?_第1张图片

骨架屏特效

现在就可以尝试添加骨架屏特效了,骨架屏特效本身就只是一个背景色向右流动的效果,所以我们需要一个渐变色背景,然后设置一个动画让背景色的background-position不断向右移动,就可以实现骨架屏的效果

对应的css代码如下:

.skeleton {background: linear-gradient(to right,#f6f7f8 0%,#edeef1 10%,#f6f7f8 20%,#f6f7f8 100%);background-size: 200% 100%;animation: flow 1s linear infinite;
}

@keyframes flow {0% {background-position: 50% 0;}100% {background-position: -150% 0;}
} 

那么有了这个骨架屏特效的代码,我们还需要看看其效果是否真的和我们预期中一样呢?

可以先把html中的内容注释掉,只保留框架部分,模拟一下数据还没加载时候的效果,然后再在需要应用骨架屏特效的地方加上.skeleton类名

我们要应用骨架屏特效的地方有背景图片、卡片标题、卡片内容、作者头像、作者姓名、留言日期,所以在这些地方加上.skeleton类名

< -->

再来看看效果:

设置文本元素占位符作为骨架屏填充

咦?生效是生效了,但是只有头部背景图和作者头像有效果,而文字部分全都没效果了,这是为啥呢?

这是因为文本元素中没有文本的时候,它没有自己的宽高,那设置background属性自然也是不会生效的,所以我们需要给它添加一个用于占位的元素,只要有一个字符,就能够充满当前行了,这里我们就填充一个 空格占位符吧

< -->

 

 

  

现在的效果如下:

可以看到这样就行了,那么接下来我们就通过js去模拟数据加载,加载完成后,将数据插入到对应元素中,并将.skeleton样式去除

js模拟数据加载效果

为了方便js获取对应元素,我们给应用了骨架屏特效的元素起一个语义化的id

< -->

 

 

  

现在就可以用js去模拟数据加载效果啦

(() => {const skeletonEls = {oHeaderImgContainer: document.getElementById("header-img-container"),oCardTitle: document.getElementById("card-title"),oCardContent: document.getElementById("card-content"),oCardAuthorAvatarContainer: document.getElementById("card-author-avatar-container"),oCardAuthorName: document.getElementById("card-author-name"),oCardAuthorDate: document.getElementById("card-author-date"),};const init = () => {const fetchData = () => {setTimeout(() => {const data = {headerImg: ``,cardTitle: "I love coding`,cardAuthorName: "Plasticine",cardAuthorDate: "Aug 13, 2022",};// 插入加载到的数据skeletonEls.oHeaderImgContainer.innerHTML = data.headerImg.trim();skeletonEls.oCardTitle.innerHTML = data.cardTitle;skeletonEls.oCardContent.innerHTML = data.oCardContent;skeletonEls.oCardAuthorAvatarContainer.innerHTML =data.cardAuthorAvatar.trim();skeletonEls.oCardAuthorName.innerHTML = data.cardAuthorName;skeletonEls.oCardAuthorDate.innerHTML = data.cardAuthorDate;// 移除 `.skeleton` 类名从而 移除骨架屏特效for (const el of Object.values(skeletonEls)) {el.classList.remove("skeleton");}}, 3000);};fetchData();};init()" style="margin: auto" />
})(); 

最终效果就像开头中的那样,大功告成!

最后

整理了75个JS高频面试题,并给出了答案和解析,基本上可以保证你能应付面试官关于JS的提问。
如何实现骨架屏效果?_第2张图片
如何实现骨架屏效果?_第3张图片
如何实现骨架屏效果?_第4张图片
如何实现骨架屏效果?_第5张图片

有需要的小伙伴,可以点击下方卡片领取,无偿分享

你可能感兴趣的