在平时web动画的开发中,会碰到一些资源加载的问题,比如动画所需要的资源还没加载完,动画就开始运行了,这样动画的体验就不是很好了。这篇文章就是专门来解决这个问题的。
比如,我们想通过渐隐渐显的动画来显示一张图片。一般是通过keyframes的方式来实现这样的动画效果,不过,在大多数的时候,如果不做一些特殊处理的话,会遇到图片还没加载完,动画就已经执行完了。这样会影响到用户的使用体验。
比如,上面的这个动画,在图片还没加载完动画就已经开始运行了,在视觉上体验就不是很好了。下面就来看看我们该如何来修复它?
问题
当我们打开一个网站的时候,浏览器为了使网站能更快的呈现在用户面前,会在下载其它资源之前(比如图片、脚本等资源)优先下载渲染html和css。
这种资源加载的策略,意味着我们在打开一个网站的时候能很快的看到网站的布局和文字内容,但是,如果你网站中用到大量的图片,这些图片可能就没这么快呈现在用户面前,就像文章开头的那个动图那样。
这里,就需要用到一些小技巧,来保证在动画在正确的时候出现。
加载事件和动画状态
浏览器提供对应监听加载事件的JavaScript方法。这个事件能监听资源的加载,比如,图片和脚本。我们可以利用这个事件来控制动画的状态。
我们将利用相关的JavaScript方法来监听资源的加载,并用它来配合animation-play-state方法来控制动画的状态。
下面是代码:
document.body.classList.add('js-loading');
window.addEventListener("load", showPage);
function showPage() {
document.body.classList.remove('js-loading');
}
首先是添加js-loading类在body元素上,这个类用来控制动画的状态,比如播放和暂停等状态。然后使用load事件来控制相关的操作。
下面将定义一个removeLoadingClass方法,它主要是在当所有的图片资源加载完的时候,删除js-loading这个类,从而播放动画。
这里需要注意的是,写完代码后,需要把代码放到html文件中,比如header里面。如果,是从外部来引入js文件,css文件将会优先被加载和渲染,这样动画将可能在资源准备好之前就开始了。
所以,才需要一个类来控制动画的状态,这样才能保证所有动画需要的资源加载后,动画才开始播放。
监听图片加载
上面代码中的方法是用来等所有的资源加载后才执行指定的方法。不过在实际的场景中,我们可能只想加载指定的资源,比如图片,在上面的那个出现问题的动画中,只需要等图片加载完后就可以了。JavaScript也提供了对应的方法,详细的可以去这里看看。
下面是修改后的代码:
// Adjust the "querySelector" value to target your image
var img = document.querySelector("img");
document.body.classList.add('js-loading');
img.addEventListener("load", removeLoadingClass);
function removeLoadingClass() {
document.body.classList.remove('js-loading');
}
animation-play-state方法
animation-play-state方法主要是用来控制动画状态的,比如播放暂停等。而且浏览器支持也非常的不错。
所以,我们就可以用来控制动画在资源加载完之前,处于暂停状态。
.js-loading *,
.js-loading *:before,
.js-loading *:after {
animation-play-state: paused !important;
}
上面几行代码,即表示当body类上有js-loading这个类的时候,动画就处于暂停状态。
当资源加载完后,删除js-loading类,从而使动画开始播放。
JavaScript失效怎么办?
在页面中运行JavaScript,我们总要问下自己,当JavaScript失效,该如何来应对?比如,一些js插件的实效等意外情况等出现,需要一套应对的方案来处理。
在我们这个例子中,就算JavaScript失效或者是加载失败,没有添加js-loading类在body 元素上,那也只是会出现刚开始提到的图片还没加载完,动画就开始运行的情况。并没有影响整个页面的运行。这种情况还是可以接受的。
下面就来实践下。
找一张足够大的图片,这张图片超过了2M。
我们可以使用chrome提供的网络功能来模拟弱网络情况下,页面运行的情况,比如3G网络。
可以去这个地址来实际体验下。
当然,为了体验更友好一点,比如,页面刚打开的时候给用户点提示,正在加载资源等提示信息。当然,这也取决于你有多少资源要加载,比如有很多的图片资源,提示用户还是很有必要的。
本文主要是从Making Animations Wait这篇文章整理而来,有删减,有疏漏或者理解不到位的地方,还请多多指教!