如今,在网站上看到加载状态非常普遍,尤其是在渐进式 Web 应用和响应式网站兴起的情况下。 这是提高“感知”性能的一种方法——也就是说,让网站感觉加载速度比实际快。
制作加载器的方法有很多——只需在 CodePen 上快速搜索 就可以看到很多示例,从动画 GIF 到复杂的动画。 虽然构建最花哨的加载器很诱人,但实际上我们只需使用最少的 CSS 和 JavaScript 就可以做得非常好。
这是一个我们可以一起制作的示例。
查看 CodePen
带有 JavaScript 淡出效果的加载器,作者为 Maks Akymenko (@maximakymenko)
在 CodePen 上。
SVG 和 CSS 是我们需要的全部内容
我假设您已经创建了一个项目,所以我们将直接跳入并从加载器开始——或者也称为“预加载器”。
SVG 是加载器的绝佳选择。 它可缩放,并且实现起来就像图像标签一样简单。 我们可以从头开始制作一个,例如在 Illustrator、Sketch 或 Figma 等图像编辑器中。 在此示例中,我将从 这里 获取一个来自 loading.io 的 SVG,这是一个制作和自定义不同加载器的不错资源。
现在我们有了 SVG 图形,可以将其放入 HTML 中
<div class="preloader">
<img src="spinner.svg" alt="spinner">
</div>
我们使用 .preloader
作为包装器,主要是因为它有助于我们在页面上定位图像,但也因为这将有助于我们在加载器工作时隐藏和显示页面内容。
让我们对其进行样式设置
.preloader {
align-items: center;
background: rgb(23, 22, 22);
display: flex;
height: 100vh;
justify-content: center;
left: 0;
position: fixed;
top: 0;
transition: opacity 0.3s linear;
width: 100%;
z-index: 9999;
}
这做了一些不仅仅是装饰的事情
- 我们使用 flexbox 属性和值将加载器直接显示在屏幕中央。
- 我们使元素占据整个屏幕的宽度和高度,并为其设置黑色(实际上是深灰色)背景。 这意味着它后面的任何内容(例如页面内容)都完全隐藏。 如果我们的页面是不同的背景颜色(例如白色),那么我们将相应地调整加载器的背景颜色。
- 位置是固定的,因此滚动不会影响它在页面上的位置。 此外,
z-index
足够高,以至于没有其他元素应该堆叠在其顶部并阻止其显示。
这是我们在浏览器中打开它时目前应该看到的内容

一些简单的 JavaScript 处理隐藏
我们有一个花哨的加载器,它覆盖了整个页面,无论我们是在小屏幕还是大屏幕上查看它。 现在我们可以编写一些逻辑,使其在一段时间后淡出。 这需要一小部分 JavaScript。
首先,让我们选择我们刚刚设置样式的 .preloader
元素
const preloader = document.querySelector('.preloader');
实际上,向加载器添加一个类将它的不透明度设置为零会更容易。 但是,它不会像我们这里所做的那样流畅,这里使用了一点 JavaScript 来创建 fadeOut
函数。
const fadeEffect = setInterval(() => {
// if we don't set opacity 1 in CSS, then
// it will be equaled to "" -- that's why
// we check it, and if so, set opacity to 1
if (!preloader.style.opacity) {
preloader.style.opacity = 1;
}
if (preloader.style.opacity > 0) {
preloader.style.opacity -= 0.1;
} else {
clearInterval(fadeEffect);
}
}, 100);
💡 jQuery 有一个函数 可以直接做到这一点。 如果您已经在项目中使用 jQuery,请利用它。 否则,使用原生 JavaScript 是可行的。
让我稍微解释一下 JavaScript。 正如注释所说,如果我们的 .preloader
元素没有设置 opacity
属性,则它将为空(""
),我们可以将其手动设置为 1,以确保它在文档加载时显示。
一旦我们知道不透明度已设置,我们就可以对其进行操作。 整个函数都包装在 setInterval
中,我们每 100 毫秒检查一次 opacity
属性,以查看它是否大于零。 只要它大于零,我们就将其值以 0.1 的增量递减,这会产生一个随着时间推移逐渐淡出元素的平滑效果。
一旦我们达到零不透明度,我们就 clearInterval
以停止脚本无限运行。 请随意调整时间和递减点以适合您的需求。
最后要做的就是调用函数。 我们将在窗口加载时调用它
window.addEventListener('load', fadeEffect);
我们有意使用 load
事件而不是 DOMContentLoaded
,因为 DOMContentLoaded
事件在文档完全加载并解析后触发。 这意味着它 *不会等待样式表、图像和子框架完成加载* *然后再执行*。 load
事件可用于检测页面是否完全加载,这正是我们想要的。 否则,该函数将在我们的 CSS 和 SVG 准备好之前开始。
将一些内容放入 HTML 并尝试一下。 这是演示
查看 CodePen
带有 JavaScript 淡出效果的加载器,作者为 Maks Akymenko (@maximakymenko)
在 CodePen 上。
恭喜! 您现在知道如何仅使用图像以及少量 CSS 和 JavaScript 构建一个非常不错的加载效果。 尽情享受吧!
这里缺少一件非常重要的事情:
.preloader
元素需要一个pointer-events: none;
属性,否则将无法与页面上的元素交互,因为不可见的加载器元素将覆盖所有内容(您实际上可以在演示中看到这一点)。 就我个人而言,我更喜欢使用第二个类并使用 CSS 更改动画,以使其更容易管理过渡。 因此它将类似于然后您的 JavaScript 只需向
.preloader
元素添加.loaded
类即可。这真是一个至关重要的步骤! 谢谢老兄
使用 jQuery 的 .fadeOut,您无需担心指针事件,因为它会在动画结束后使用 display: none 隐藏元素
您好,好主意,我一直在寻找类似的东西。 我有一些问题
– 您能否使用 css 关键帧和无限重复动画来代替 JavaScript?
– 在文档加载时隐藏加载器是否有意义? 也许从元素中删除 .preloader 类,或者为了简单起见,甚至完全销毁它
– css 和 js 应该内联在 html 中(style、script),以便加载器尽快呈现吗?
谢谢
John
我会简单地将 display: none 应用于“.preloader.loaded”。 它更直接,具有更好的浏览器支持并且更具语义。
非常感谢分享…….
@John
– 是的,您可以。 此演示中的加载器实际上并没有使用 JavaScript 进行主要动画,而是使用了 SVG 动画。 JavaScript 用于页面加载后的淡出效果。 就我个人而言,我喜欢使用 SVG 动画(甚至存储在 SVG 文件中的 CSS 动画),因为它将所有内容作为单个图像文件自包含。
– 在这里,我们只是在文档加载时隐藏元素,但通常我会销毁它。 正如 Rudi 所提到的,您可以使用 jQuery 的 fadeOut() 方法来淡出和删除加载器。 但是,如果您不使用 jQuery,也可以通过 setTimeout() 手动执行此操作,该方法等待淡出完成,然后删除元素。
– 您可以将加载器的 CSS 分离到自己的文件中,该文件位于最前面,以便在任何其他内容之前加载,尽管根据您要等待加载的内容类型,它可能无关紧要。 我通常不这样做,也没有遇到任何问题。 但是 JavaScript 只有在页面完成加载后才会执行,因此它放置的位置实际上并不重要。
嗯,我刚刚做了一个! https://codepen.io/jeffedsell/pen/GRKLMEB
不错
只有我讨厌页面加载器吗? 让我想起了 Flash 网站。
接下来会怎样?10mb 的单页网站加上进度条?
它主要用于使用 Three.js 或其他资源密集型进程的网站,这些进程需要一点时间来加载。但结果总是令人惊叹的!
或者,您可以在 else 条件 (opacity=0) 中设置 preloader.style.display=”none”。
如果这是 Stack Overflow,我会投票支持这个答案。
为什么在 JS 中以
0.01
为增量手动降低加载器的透明度,而不是使用 CSStransition
来使其更平滑?你可以直接在1
和0
之间进行过渡?如果 JavaScript 失败会发生什么?覆盖层是否会一直可见,从而让人感觉页面加载需要无限长的时间?如果页面加载/渲染速度慢到需要“加载”指示器,那么是否可以认为应该将时间花在加快加载/渲染速度上?
我已经自信地称自己为网页开发者几年了,而页面加载器一直是我的一种潘多拉魔盒。我怀疑它们从头开始制作并不复杂;但是,不可否认的是,我太懒了,从未进行过任何挖掘。
这篇博文我花了五分钟就读完了,它完全为我解开了页面加载器的谜团。
出色的工作!
页面加载后,页面元素由于 z-index 而无法点击。如何处理这种情况?
说得对!您可以向
.preloader
添加pointer-events: none;
,这应该可以解决问题。