如何实现骨架屏效果?

article/2025/9/14 23:32:11

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

首先思考如何实现

思考实现方式

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

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

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

静态结构

<div class="card"><<img src="https://unsplash.com/photos/EaB4Ml7C7fE/download?ixid=MnwxMjA3fDB8MXxzZWFyY2h8MTN8fGNvZGV8ZW58MHx8fHwxNjYwMzQwOTQ4&force=true"alt=""/></header><main><h3>I love coding!</h3><p>Talk is cheap. Show me the code.</p><section class="author"><div class="author-avatar"><img src="https://pixabay.com/get/g9ac59ef391ebfbe7b3303ed0278986a31783bedd580d5e097980ed990d9bf646b5dc44932b18fd633df1813686e4f809.png?attachment=" alt="" /></div><div class="author-info"><!-- 名字 --><strong>Plasticine</strong><!-- 日期 --><small>Aug 13, 2022</small></div></section></main" style="margin: auto" />
</div> 

再写一些基础样式

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;
} 

现在的效果如下:

骨架屏特效

现在就可以尝试添加骨架屏特效了,骨架屏特效本身就只是一个背景色向右流动的效果,所以我们需要一个渐变色背景,然后设置一个动画让背景色的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类名

<div class="card"><<img src="https://unsplash.com/photos/EaB4Ml7C7fE/download?ixid=MnwxMjA3fDB8MXxzZWFyY2h8MTN8fGNvZGV8ZW58MHx8fHwxNjYwMzQwOTQ4&force=true"alt=""/> --></header><main><h3 class="skeleton"><!-- I love coding! --></h3><p class="skeleton"><!-- Talk is cheap. Show me the code. --></p><section class="author"><div class="author-avatar skeleton"><!-- <imgsrc="https://pixabay.com/get/g9ac59ef391ebfbe7b3303ed0278986a31783bedd580d5e097980ed990d9bf646b5dc44932b18fd633df1813686e4f809.png?attachment="alt=""/> --></div><div class="author-info"><!-- 名字 --><strong class="skeleton"><!-- Plasticine --></strong><!-- 日期 --><small class="skeleton"><!-- Aug 13, 2022 --></small></div></section></main" style="margin: auto" />
</div> 

再来看看效果:

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

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

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

<div class="card"><<img src="https://unsplash.com/photos/EaB4Ml7C7fE/download?ixid=MnwxMjA3fDB8MXxzZWFyY2h8MTN8fGNvZGV8ZW58MHx8fHwxNjYwMzQwOTQ4&force=true"alt=""/> --></header><main><h3 class="skeleton">&nbsp;<!-- I love coding! --></h3><p class="skeleton">&nbsp;<!-- Talk is cheap. Show me the code. --></p><section class="author"><div class="author-avatar skeleton"><!-- <imgsrc="https://pixabay.com/get/g9ac59ef391ebfbe7b3303ed0278986a31783bedd580d5e097980ed990d9bf646b5dc44932b18fd633df1813686e4f809.png?attachment="alt=""/> --></div><div class="author-info"><!-- 名字 --><strong class="skeleton">&nbsp;<!-- Plasticine --></strong><!-- 日期 --><small class="skeleton">&nbsp;<!-- Aug 13, 2022 --></small></div></section></main" style="margin: auto" />
</div> 

现在的效果如下:

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

js模拟数据加载效果

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

<div class="card"><<img src="https://unsplash.com/photos/EaB4Ml7C7fE/download?ixid=MnwxMjA3fDB8MXxzZWFyY2h8MTN8fGNvZGV8ZW58MHx8fHwxNjYwMzQwOTQ4&force=true"alt=""/> --></header><main><h3 class="skeleton" id="card-title">&nbsp;<!-- I love coding! --></h3><p class="skeleton" id="card-content">&nbsp;<!-- Talk is cheap. Show me the code. --></p><section class="author"><div class="author-avatar skeleton" id="card-author-avatar-container"><!-- <imgsrc="https://pixabay.com/get/g9ac59ef391ebfbe7b3303ed0278986a31783bedd580d5e097980ed990d9bf646b5dc44932b18fd633df1813686e4f809.png?attachment="alt=""/> --></div><div class="author-info"><!-- 名字 --><strong class="skeleton" id="card-author-name">&nbsp;<!-- Plasticine --></strong><!-- 日期 --><small class="skeleton" id="card-author-date">&nbsp;<!-- Aug 13, 2022 --></small></div></section></main" style="margin: auto" />
</div> 

现在就可以用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: `<imgsrc="https://unsplash.com/photos/EaB4Ml7C7fE/download?ixid=MnwxMjA3fDB8MXxzZWFyY2h8MTN8fGNvZGV8ZW58MHx8fHwxNjYwMzQwOTQ4&force=true"alt=""/>`,cardTitle: "I love coding<img src="https://pixabay.com/get/g9ac59ef391ebfbe7b3303ed0278986a31783bedd580d5e097980ed990d9bf646b5dc44932b18fd633df1813686e4f809.png?attachment="alt=""/>`,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的提问。



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


http://chatgpt.dhexx.cn/article/8q5mVNxB.shtml

相关文章

啥是骨架屏

&#xff08;一&#xff09;什么是骨架屏 骨架屏可以理解为是当数据还未加载进来前&#xff0c;页面的一个空白版本。在页面完全渲染完成之前&#xff0c;用户会看到一个样式简单&#xff0c;描绘了当前页面的大致框架的页面&#xff0c;然后骨架屏中各个占位部分被实际资源完…

前端骨架屏方案与实践

对于依赖接口渲染的页面&#xff0c;在拿到数据之前页面往往是空白的&#xff0c;为了提示用户当前正在加载中&#xff0c;往往会使用进度条、loading图标或骨架屏的方式。 对于前两种方案而言&#xff0c;实现比较简单&#xff1b;本文主要研究骨架屏的实现方案。 骨架屏(Ske…

网页骨架屏自动生成方案(dps)

来源&#xff1a;花满楼 https://zhuanlan.zhihu.com/p/74403911 什么是骨架屏&#xff1f; 什么是骨架屏呢&#xff1f;骨架屏(Skeleton Screen)是指在页面数据加载完成前&#xff0c;先给用户展示出页面的大致结构&#xff08;灰色占位图&#xff09;&#xff0c;在拿到接口数…

骨架屏

&#xff08;一&#xff09;什么是骨架屏 骨架屏可以理解为是当数据还未加载进来前&#xff0c;页面的一个空白版本。在页面完全渲染完成之前&#xff0c;用户会看到一个样式简单&#xff0c;描绘了当前页面的大致框架的页面&#xff0c;然后骨架屏中各个占位部分被实际资源完…

Vue中实现骨架屏的多种方式

vue-cli项目首页加载缓慢想要使用骨架屏效果&#xff0c;经过几天的实践&#xff0c;这里学习并记录一下vue项目自动生成骨架屏方法。 前言&#xff1a;骨架屏的作用主要是在网络请求较慢时&#xff0c;提供基础占位&#xff0c;当数据加载完成&#xff0c;恢复数据展示。这样给…

骨架屏原理——面试别再被挨打了

目录 前言 骨架屏是什么 骨架屏原理 用途&#xff1a; &#xff08;一&#xff09;简单实现 &#xff08;二&#xff09; vue项目中的构建 &#xff08;三&#xff09;自动化方案 前言 同样是之前练手项目中的&#xff0c;emmm,知道干嘛用的&#xff0c;没了解过具体原理…

性能测试总结之内存泄露和内存溢出

刚刚做完了一个项目的性能测试&#xff0c;“有幸”也遇到了内存泄露的案例&#xff0c;所以在此和大家分享一下。 主要从以下几部分来说明&#xff0c;关于内存和内存泄露、溢出的概念&#xff0c;区分内存泄露和内存溢出&#xff1b;内存的区域划分&#xff0c;了解GC回收机…

内存泄露与内存溢出的区别及解决方法

内存溢出与泄露的区别 内存溢出 out of memory&#xff0c;是指程序在申请内存时&#xff0c;没有足够的内存空间供其使用&#xff0c;出现out of memory&#xff1b;比如申请了一个integer,但给它存了long才能存下的数&#xff0c;那就是内存溢出。 内存泄露 memory leak&…

jvm故障 内存泄露和内存溢出总结

目录 内存泄漏memory leak 内存泄漏的分类&#xff08;按发生方式来分类&#xff09; 内存泄露的场景 静态集合类 / 长生命周期的对象持有短生命周期对象的引用 / 单例模式 /类加载器 各种连接&#xff0c;如数据库连接、网络连接和IO连接等 变量不合理的作用域 内部类持…

JVM——内存泄漏与内存溢出

内存泄漏与内存溢出 1. 面试题 什么是内存泄漏和什么是内存溢出 (陌陌) Java存在内存泄漏吗&#xff0c;内存泄漏的场景有哪些&#xff0c;如何避免(百度) Java 中会存在内存泄漏吗&#xff0c;简述一下&#xff1f;(猎聘) 内存泄漏是怎么造成的&#xff1f;(拼多多、字节跳动)…

Java中内存溢出和内存泄露详解

1、内存溢出&#xff08;OOM&#xff09; 在程序中导致程序崩溃的两种原因有&#xff1a; ①、空指针、下标越界等异常&#xff0c;这类问题主要原因是因为代码写的有问题 ②、还有一类问题是&#xff0c;代码看着也没有问题&#xff0c;在进行GC时&#xff0c;回收也没有空出足…

内存泄漏和内存溢出的区别

内存泄漏就是在jvm堆中生成的对象&#xff0c;经过垃圾回收器回收后也无法得到有效的释放&#xff0c;则会导致可用的虚拟机可分配的内存越来越少。最终可能导致内存溢出。 以发生的方式来分类&#xff0c;内存泄漏可以分为4类&#xff1a; 1、常发性内存泄漏。发生内存泄漏的…

什么是内存泄漏和内存溢出

目录 一、内存溢出 (OutOfMemory)二、内存泄漏 (Memory Leak) 一、内存溢出 (OutOfMemory) 它是指程序在申请内存时&#xff0c;没有足够的内存空间供其使用&#xff0c;抛出OutOfMemory异常。 比如申请了一个8MB空间&#xff0c;但是当前内存可用空间只有5MB&#xff0c;那么…

内存溢出和内存泄漏

内存溢出&#xff1a; 一、内存溢出相对于内存泄漏来说&#xff0c;尽管更容易被理解&#xff0c;但是同样的&#xff0c;内存溢出也是引发程序崩溃的罪魁祸首之一。 二、由于GC一直在发展&#xff0c;所有一般情况下&#xff0c;除非应用程序占用的内存增长速度非常快&#…

Vim替换命令substitute介绍

原文地址&#xff1a;再谈Vim substitute替换命令-Vim入门教程(54) 在Vim替换命令一文介绍过&#xff0c;substitute 命令的语法格式为&#xff1a;:[range]s[ubstitute]/{pattern}/{string}/[flags]。 [flags] 表示可选的标志位&#xff0c;常用的包括 g、c、n、e 等。其中&…

VIM替换命令%s

[rootlocalhost 09:03:42 /home/test]# cat vim_test.txt linux nginx aabb bbcc ccdd vim vim_test.txt 进入编辑模式 输入指令 :%s/bb/zz/gc 全局替换&#xff0c;带确认 按y对搜索项替换第一个 按y对搜索项替换第二个 这种操作方法 &#xff0c;查看替换过程与效果。避…

八皇后问题c语言算法

目录 [TOC] 问题分析&#xff1a; 相信八皇后规则的问题&#xff0c;大家都很熟悉&#xff0c;接下来是如何分析回溯法的应用。回溯法与图里面的深度优先遍历非常的类似&#xff0c;就是&#xff0c;在满足题目条件时候&#xff0c;它总是优先选择第一个&#xff0c;当不满足…

八皇后算法

两个皇后都不能处于同一行、同一列或同一斜线上 讨论如果是八个皇后&#xff0c;即存在于8*8的行列式中&#xff0c;每行每列一定存在一个皇后&#xff0c;现在我们用queen[row]col 表示在第row行的皇后处于第col列&#xff0c; 位置的选定&#xff0c;5人 然后判断此时皇后所…

【算法】八皇后问题

1. 问题描述 在 8 * 8 的国际象棋棋盘上摆放八个皇后&#xff0c;任意两个皇后不能处于同一行、同一列或同一斜 线上&#xff0c;请求出所有的摆法。 2. 算法描述 用回溯算法来考虑此问题&#xff0c;在放置皇后之前判断该位置是否会产生冲突。有冲突就继续判断 下一个位置&…

八皇后问题算法解析

八皇后问题&#xff0c;是一个古老而著名的问题&#xff0c;是回溯算法的典型案例。 该问题是国际西洋棋棋手马克斯贝瑟尔于1848年提出&#xff1a;在88格的国际象棋上摆放八个皇后&#xff0c;使其不能互相攻击&#xff0c; 即任意两个皇后都不能处于同一行、同一列或同一斜线…