码云笔记前端博客
Home > JavaScript > 常用的网页加载进度条实现方法

常用的网页加载进度条实现方法

2018-12-26 分类:JavaScript 作者:码云 阅读(5522)

本文共计9918个字,阅读时间预计25分钟,干货满满,记得点赞加收藏哦

  常用的网页加载进度条,今天为大家带来的进度条实现不是我们动画,而是根据页面的内容实时获取页面载入的进度,加载进度条在页面中见到的非常多,相信大家在一些网页中看到过类似交互效果。随着HTML5的普及,各种CSS3动画及JS特效在网页中层出不穷,PC端载入数据的速度还算可以,移动端相对要慢很多,如果图片或脚本没有完全载入的时候,用户在操作中就会出现各种问题,所以在这里我们就需要一个进度条的操作。如果我们没有这样一个进度条,展现给用户的就是一个空白页面等待,这个用户体验是非常不好的,所以大家在网上也会看到很多的进度条。如果只是单单实现一个进度条效果是非常简单的,但不是根据数据的载入进行侦测的进度条,那样会看起来会非常别扭,就会导致进度条加载完,数据还没有出来的尴尬境遇,因此我们需要对数据载入进行侦测,以更加人性化的方式给用户展现。

预备知识

  • 代码编辑器
  • HTML5+CSS3
  • Javascript

制作进度条

网页加载进度条误区

很多小伙伴说我们可不可以给进度条加一个定时器呢?比如说我们让它延迟3秒钟,或者是5秒钟之后加载我们相关内容,这种方法呢并不是说不行,如果这个网页让它延迟3秒钟之后,大多数主题和图像都加载出来了,也是可以的。

用定时器可以解决一部分问题,但是弊端也是很大的。比如说页面我们已经打开过了,已经有缓存存在本地了,再用定时器这个效率就非常低了,因为请无论有没有这个缓存它都要执行3秒的延迟,所以说效率和体验都不太良好。之所以有的小伙伴用定时器,因为在网上搜索进度条实现方法大部分都是用定时器来完成的,这种方法只能说是在表现上实现了进度条,但实质上不是真正的进度条。

网页加载进度条误区

先用定时器方法来给大家演示一下布局结构,我们在body中加载页面内容,主要部分就是图像,代码也就是几十kb,有的大的banner图甚至可以达到1兆多甚至还要大,所以页面上的图像是我们加载的重点。我找了几张比较大的图给大家做演示,为的就是让它加载慢一点,代码如下:

HTML代码:

1
2
3
4
5
6
7
<!-- 加载代码-->
<div class="loading"></div>
<img src="../img/1.jpg">
<img src="../img/2.jpg">
<img src="../img/3.jpg">
<img src="../img/4.jpg">
<img src="../img/bigimg.jpg">

CSS代码:

1
2
3
4
5
6
7
8
9
.loading{
    width: 100%;
    height:100%;
    position: fixed;
    top: 0;
    left: 0;
    z-index: 100;
    background: #fff;
}

我们来看一下此时效果:

定时器加载网页

此时我们看到div已经将我们网页全部遮住了,如果页面上只有这么一个白色那就很枯燥,我们不知道它是什么东西,所以在这我们就需要加载一个小动画,那么这个动画该如何做呢?一种方法我们可以加载图像,另外还可以使用css3来加载几个有意思的小动画,我这里推荐大家如何去找有趣味的图像,打开这个网址:preloaders这是一个可以在线生成GIF图标的网站,大家可以根据自己的需要选择,也可以修改相关颜色参数等设置,默认的话直接DOWNLOAD下来就可以了。

在线生成GIF图标

将这个GIF图引入到页面,我们在原先div内插入GIF图片,class为pic

1
2
3
<div class="loading">
    <div class="pic"></div>
</div>>

CSS样式:

1
2
3
4
5
6
7
8
9
10
11
12
.loading .pic{
    width: 64px;
    height: 64px;
    border:1px solid red;
    background: url(../img/loading.gif);
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    margin: auto;
}

在页面上的效果:

页面loading效果

接下来我们看一下js部分,定时3秒隐藏loading加载页面内容

1
2
3
4
5
$(function(){
    setInterval(function(){
        $(".loading").fadeOut();
    },3000)
})

这种内容只是写死的数据,而不是真正反映加载我们的内容,所以这种方法不是完全正确的方法。这里只是介绍在body我们如何布局结构,直接加在div上就可以,或者说我们可以直接在js内做这步操作,直接把它当成字符串添加给body即可,就不用再body内写那样的一个内容了,最后效果实现是一样的:

1
2
3
4
5
6
7
$(function(){
    var loading = '<div class="loading"><div class="pic"></div></div>';
    $("body").append(loading);
    setInterval(function(){
        $(".loading").fadeOut();
    },3000)
})

通过加载状态事件制作进度条

通过加载状态事件制作进度条我们需要用到哪些知识点呢,我们看一下:

1
2
document.onreadystatechange    页面加载状态时的事件
document.readyState                   返回当前文档的状态

document.onreadystatechange 我们在向服务器端发送请求的时候服务端也是给我们不同的事件进行返回,我们用它来检测一下页面状态的改变。

document.readyState 这个是服务端返回的请求,当然这两个是要配合使用的。

这两个方法其实在我们网站中用到最多的,其实你在网上看到很多的这种加载这种进度条呢基本上都是使用这两个事件做的,这个才是我们要实时检测我们要加载的数据,所以接下来我们就通过这两个事件来完成这个小案例。

当然document.readyState还有这么几个状态,在这里我们向服务器端发送请求的时候有这样几个过程,就是:

  • uninitialized -还未开始载入
  • loading -载入中
  • interactive -已加载,文档与用户可以开始交互
  • complete -载入完成

在这个整个过程中呢,我们主要要的就是最后一个事件,那么这个事件就是完成之后就是我们的返回结果,表示载入成功了,这个时候就可以把进度条隐藏掉显示我们页面的主体内容了。下面我们根据这样几个知识点来介绍这样一个用法。

基本布局和上面一样,这里不再多赘述,我们来看看这几个时间的用法

1
document.onreadystatechange = function () {}

document.onreadystatechange方法和我们之前写的window.onload方法是一样的,function代表的是我们文档改变的时候要和执行的内容,接着我们就来看一下document.readyState的四个状态,我们可以用console.log()分别打印出来在后台看一下效果,

1
2
3
document.onreadystatechange = function () {
    console.log(document.readyState);
}

后台显示:

后台打印document.readyState

我们通过上图看到console.log返回两个事件,当然这是已经加载过这个图像了,所以请求服务器端是比较快的,一个是页面载入 uninitialized ,一个是载入完成complete,前两个事件我们是没法检测的,其实前几个事件我们不需要看,我们只需要看最后一个,如果出现complete这个值说明我们请求已经成功了,那么我们看一下怎么写。

1
document.readyState == "complete"

这个时候就代表我们请求完成了,在这里我们就可以做一个事件了,如果我们这个结果等于complete,然后我们就可以写一个结果,可以将load给它隐藏掉。

1
2
3
4
5
document.onreadystatechange = function () {
    if(document.readyState == "complete"){
        $(".loading").fadeOut();
    }
}

看一下效果:

document.readyState进度条实现事件

这个时候大家可以看到,加载是非常快的,如果等于这个结果后,自动就将上面这个div层给隐藏掉了,这个事件方法是简单又粗暴的,内容也是非常的容易。大家只要记住这两个主要事件就可以了,里面的内容可以复杂的写,我这里只是隐藏掉,大家可以根据自己的要求进行设计。

css3进度条小动画

在上面例子中的进度条我们用的是一张图像,我们代码要完成一个动画可能需要几b的文件或者说是几KB的文件,但是图像要比我们代码多一些,那么从长远角度来讲,代码会让我们的页面加载速度更快一些,所以尽量不用图像就不用图像。那这样我们就介绍一个css3小动画,通过loading这个网站可以为我们提供进度条动画。

css3动画制作

包括SVG、CSS、GIF这些格式,功能很强大,大家可以对图像进行设置它的属性,动画大小、速度快慢、颜色等等

css3动画相关属性设置方法

这个网站里面包含的类型也是非常多的,我们可以直接拿来用,可以生成GIF,或者是css文件,我们把这个css放到我们样式规则中就可以用了,当然样式很多,大家可以看一下,在可以满足我们需求的情况下,直接拿来用就可以用。满足不了呢就只能自己来写。

接下来就为大家实现一下,玩一下css3动画,布局还和上面说的一样,我们需要改一下pic,然后就是把我们下载好的css文件引入到我们demo中。

我们下载好的文件是这个样子的:

loading css3动画文件

我们需要把我们的pic的宽高改一下,位置不变,只是不在引用图像,而是刚刚我们生成好的css动画文件,此时的HTML布局:

1
2
3
4
5
6
7
8
9
<div class="loading"&lgt;
    <div class="pic">
        <i></i>
        <i></i>
        <i></i>
        <i></i>
        <i></i>
    </div>
</div>

CSS动画初步效果样式(没有做兼容):

1
2
3
4
5
6
7
8
9
10
11
12
.loading{width: 100%;height:100%;position: fixed;top: 0;left: 0;z-index: 100;background: #fff;}
.loading .pic{width: 50px;height: 50px;position: absolute;top: 0;bottom: 0;left: 0;right: 0;margin: auto;}
.loading .pic i{display: block;float: left;width: 6px;height: 50px;background: #399;margin: 0 2px;transform: scaleY(0.4);
animation: load 1.2s infinite;}
.loading .pic i:nth-child(2){animation-delay: 0.1s;}
.loading .pic i:nth-child(3){animation-delay: 0.2s;}
.loading .pic i:nth-child(4){animation-delay: 0.3s;}
.loading .pic i:nth-child(5){animation-delay: 0.4s;}
@keyframes load{
    0%,40%,100%{transform:scaleY(0.4)}
    20%{transform:scaleY(1)}
}

如何做兼容呢?这类推荐大家一个css3工具,打开Autoprefixer将我们刚刚写好的css代码粘贴过来进行兼容操作,最终完整css代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
.loading{width: 100%;height:100%;position: fixed;top: 0;left: 0;z-index: 100;background: #fff;}
.loading .pic{width: 50px;height: 50px;position: absolute;top: 0;bottom: 0;left: 0;right: 0;margin: auto;}
.loading .pic i{display: block;float: left;width: 6px;height: 50px;background: #399;margin: 0 2px;-webkit-transform: scaleY(0.4);-ms-transform: scaleY(0.4);transform: scaleY(0.4);
-webkit-animation: load 1.2s infinite;
        animation: load 1.2s infinite;}
.loading .pic i:nth-child(2){-webkit-animation-delay: 0.1s;animation-delay: 0.1s;}
.loading .pic i:nth-child(3){-webkit-animation-delay: 0.2s;animation-delay: 0.2s;}
.loading .pic i:nth-child(4){-webkit-animation-delay: 0.3s;animation-delay: 0.3s;}
.loading .pic i:nth-child(5){-webkit-animation-delay: 0.4s;animation-delay: 0.4s;}
@-webkit-keyframes load{
    0%,40%,100%{-webkit-transform:scaleY(0.4);transform:scaleY(0.4)}
    20%{-webkit-transform:scaleY(1);transform:scaleY(1)}
}
@keyframes load{
    0%,40%,100%{-webkit-transform:scaleY(0.4);transform:scaleY(0.4)}
    20%{-webkit-transform:scaleY(1);transform:scaleY(1)}
}

有了这个工具我们就可以将不兼容的代码做一个兼容的转换,就不需要我们一个个去写,那样的话就非常费力的,这个工具是不是很强大,哈哈,拿走不谢。

这个css3 代码完整之后我们就可以把我们的js补充完整了,这个js和之前写的一样,已经讲过了,不再赘述,切记引入jQuery哦。

1
2
3
4
5
document.onreadystatechange = function () {
    if(document.readyState == "complete"){
        $(".loading").fadeOut();
    }
}

我们看一下最终的效果:

css3进度条小动画

定位在头部的进度条

这个方法非常简单,就是采用了一个页面从上带下的逐次加载的数据结构这样一个程序,我们一起来看一下具体实现方法。

HTML代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<div class="loading">
    <div class="pic">
    </div>
</div>
<header>
    <img src="../img/bigpic.jpg" />>
    <img src="../img/bigimg.jpg" />
</header>
<section class="banner">
    <img src="../img/1.jpg" />
    <img src="../img/2.jpg" />
</section>
<section class="about">
    <img src="../img/3.jpg" />
    <img src="../img/4.jpg" />
</section>
<section class="pro">
    <img src="../img/bigimg.jpg" />
    <img src="../img/bg2.jpg" />
</section>
<section class="news">
    <img src="../img/bigpic.jpg" />
    <img src="../img/bigimg.jpg" />
</section>
<footer>
    <img src="../img/bigpic.jpg" />
    <img src="../img/bigimg.jpg" />
</footer>

在HTML代码中,大家可以看到,我写了几大块内容来作为静态数据的加载,我们根据顺序来做,比如说我们页面走到头部这个地方了,写一个代码块,这个方法呢也就是说有一些特殊的页面会用到,但是这个方法不如我们之前讲到的实际,因为这里会写到好多内容。比如我们页面走到header部分了,我们用一个animate动画,我们改变一下它的宽度值,即走到这个地方它的宽度值,以此类推下面几个部分一样,通过animate动画设定不一样的宽度值表示走的多长,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
<div class="loading">
    <div class="pic">
    </div>
</div>
<header>
    <img src="../img/bigpic.jpg" />
    <img src="../img/bigimg.jpg" />
</header>
<script>
    $(".loading .pic").animate({
        width: "10%"
    }, 100)
</script>
<section class="banner">
    <img src="../img/1.jpg" />
    <img src="../img/2.jpg" />
</section>
<script>
    $(".loading .pic").animate({
        width: "30%"
    }, 100)
</script>
<section class="about">
    <img src="../img/3.jpg" />
    <img src="../img/4.jpg" />
</section>
<script>
    $(".loading .pic").animate({
        width: "50%"
    }, 100)
</script>
<section class="pro">
    <img src="../img/bigimg.jpg" />
    <img src="../img/bg2.jpg" />
</section>
<script>
    $(".loading .pic").animate({
        width: "80%"
    }, 100)
</script>
<section class="news">
    <img src="../img/bigpic.jpg" />
    <img src="../img/bigimg.jpg" />
</section>
<script>
    $(".loading .pic").animate({
        width: "95%"
    }, 100)
</script>
<footer>
    <img src="../img/bigpic.jpg" />
    <img src="../img/bigimg.jpg" />
</footer>
<script>
    $(".loading .pic").animate({
        width: "100%"
    }, 100, function() {
        $(".loading").fadeOut();
    })
</script>

CSS代码:

1
2
.loading{width: 100%;height:100%;position: fixed;top: 0;left: 0;z-index: 100;background: #fff;}
.loading .pic{width: 0%;height: 5px;position: absolute;top: 0;left: 0;background: #0044CC;}

在进度条走到100%的时候我们要将进度条隐藏,这样就要加一个function函数来隐藏进度条。但是这种有一个问题,就是我们看着这个东西都加载完了,但是这个图只是把这个数据载入进来了,它有的图呢是从上到下慢慢加载下来的,这个到不影响我们这个页面,因此,这个方法大家也可以使用,这个就是采用了从上到下执行顺序来完成的这个效果。

实时获取加载数据的进度条

接下来我将带领大家完成在项目中比较实用的实时获取加载数据的进度条方法,上面的进度条例子都是动画,也没有实时获取数据。有些网站呢就是从0到100%逐渐过度的,也能看到相应数字的变化,这个时候呢,这个用户在等待起来呢会觉得我们有一个盼头,等到它到100%的时候就可以将我们的数据加载出来,这样就比我们之前提供的方法更好用一些,更加有好些。

实现这个实时获取加载数据的进度条功能我们需要哪些知识呢?

  • 建立图像对象:图像对象名称 = new Image()
  • 属性:border、complete、height....
  • 事件:onload、onerror、onkeydown、onkeypress...
  • src的属性一定要卸载onload后面,否则程序在IE中会出错,因为是缓存的原因

这里的进度条使用纯css3来写的动画效果,很简单,还有不会css3的小伙伴,下去补补课,稍后大家可以将我的代码下载下来学习,我主要还是带大家来做js部分。

HTML代码:

1
2
3
4
5
6
7
8
9
10
11
<div class="loading">
    <div class="pic">
        <span></span>
        <b>0%</b>
    </div>
</div>
<img src="../img/bigimg.jpg" />
<img src="../img/bigimg.jpg" />
<img src="../img/bigimg.jpg" />
<img src="../img/bigimg.jpg" />
<img src="../img/bigimg.jpg" />

CSS代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
* {
    margin: 0;
    padding: 0;
}

.loading {
    width: 100%;
    height: 100%;
    position: fixed;
    top: 0;
    left: 0;
    z-index: 100;
    background: #fff;
}

.loading .pic {
    width: 100px;
    height: 100px;
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    margin: auto;
    font-size: 30px;
    text-align: center;
    line-height: 100px;
}

.loading .pic span {
    display: block;
    width: 80px;
    height: 80px;
    position: absolute;
    top: 10px;
    left: 10px;
    border-radius: 50%;
    box-shadow: 0 3px 0 #666;
    -webkit-animation: rotate 1s infinite linear;
    animation: rotate 1s infinite linear;
}

@-webkit-keyframes rotate {
    0% {
        -webkit-transform: rotate(0deg);
    }
    100% {
        -webkit-transform: rotate(360deg);
    }
}

@keyframes rotate {
    0% {
        transform: rotate(0deg);
    }
    100% {
        transform: rotate(360deg);
    }
}

接下来我们看一下js怎么写,首先引入jQuery库,将文档加载完,当然这是要区别window.onload只是不让我们这个文档提前加载的,如果我们想要定义一个预加载的话,一般会这么做,我们定一个var=new Image()这么一个对象,预加载的话我们需要给它定义一个图片img.src = "pic.jpg",然后我们会这样写,当img.onload成功的时候给它一个事件,比如说已经成功了,获取数据指定到某一个图像上,或者指定到某一个元素上,或者给它返回一个结果。一般的图像都是如下代码这样一个定义方式:

1
2
3
4
5
6
7
$(function(){
    var img = new Image();
    img.src = "tupian "
    img.onload = function () {
       
    }
})

当然我在前已经说过了,我们一般会把src放到onload事件下面,这个就是为了解决缓存的问题,如果有缓存的话,就会忽略掉这个代码,就是这个执行的东西没有了,所以我们一般会把src放到onload事件下面,如下代码:

1
2
3
4
5
6
7
$(function(){
    var img = new Image();
    img.onload = function () {
       
    }
    img.src = "tupian "
})

当然上面代码只是针对的一张图像,只是给大家提供个思路。而我们页面中的图像是非常多的,我们一般这样子做,在外面定义一个var img = $("img");这个呢大家都知道就是把我们所有的img元素获取过来了,获取过来元素之后我们要给它加一个each循环一下,在循环内定义一个oImg,外层我们在定义一个变量num,表是从0开始的,每次执行的时候让num++,然后在each中我们把这个图像给它复制过来,让oImg对象的src指定到咱们所有图像的属性,也就是每一次循环都给它一个图像的路径,那么既然是每一次,我们就通过变量i来传递过来。

1
2
3
4
5
6
7
8
$(function(){
    var img = $("img");
    var num = 0;
    img.each(function(i) {
        var oImg = new Image();
        oImg.src = img[i].src;
    })
})

然后我们开始写load了,在load里面将num进行++,这里我们主要做这样一个判断,因为这个i是可以实时获取到我们所有图像, 所以如果num数量等于i的时候, 将loading元素获取过来进行隐藏就可以了。

现在我们来实时的获取一下数据,首先我们获取一下显示数字的内容,通过html()方法更改一下结构,然后我们让num这个值变化的,因为它是从0开始的,用num除以个数,这个图像的个数肯定是固定好的,而$("img").size()呢就是它的个数,这个个数除出来肯定是个小数,为了获取到这个个数我们可以让它乘以100,这个时候获取到的数据0到100了,然后取整。但是我需要这个数据显示百分号,再加上一个字符串百分号,这个时候数据就可以了。但是这里有一个问题,当页面数据加载完成即100%时,如果是num与i相等那么页面就会一直在100%的那个状态,不会显示主界面,所以我们将代码逻辑改成(if num>=i)这样设置就可以避免这个问题。

我这里的图片都是做测试用的,可能看的不太效果明显,所以大家在尝试的时候选择图片越大数据越大这个进度条效果看的越明显。

这里我们还需要解决这么一个bug,有些时候不可避免的页面上会有GIF图像,当这个GIF图像大的时候可能会多次请求这个onload,所以我们在加载之前将oImg对象的onload先给它清掉oImg.onload = null;这个时候就会清掉我们重复请求。

完整js代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
$(function(){
    var img = $("img");
    var num = 0;
    img.each(function(i) {
        var oImg = new Image();
       
        oImg.onload= function () {
                        oImg.onload = null;
            num++;
           
            $(".loading b").html(parseInt(num/$("img").size()*100) + "%");
           
            if(num >= i){
                $(".loading").fadeOut();
            }
        }
       
        oImg.src = img[i].src;
    })
})

源码下载:源码

结束语

以上就是全部关于进度条效果的实现的全部内容,每种方法都有各自的特色,当然代码还不是很完美,还有一定的弊端,比如说我们页面可能会有视频,那么视频的制作方法也是一样的,我定义一个视频的属性,给属性获取一个加载的进度,当然页面放视频还是少数的,我们这个代码还是能够解决大多数的问题,当然大家也可以在网上找一些更加酷炫的效果,也希望大家通过上面的例子下去多练习,有不明白的地方可以留言探讨,语句有不通顺的地方也希望大家海涵。

「除特别注明外,本站所有文章均为码云笔记原创,转载请保留出处!」

赞(7) 打赏

觉得文章有用就打赏一下文章作者

支付宝
微信
7

觉得文章有用就打赏一下文章作者

支付宝
微信

上一篇:

下一篇:

你可能感兴趣

共有 3 条评论 - 常用的网页加载进度条实现方法

  1. 洛阳纸贵 Linux Chrome 62.0.3202.84

    学习了,思路不错

  2. 晴空 Linux Chrome 62.0.3202.84

    很不错的方法

    1. 码云 Windows 7 Chrome 69.0.3497.100

      @晴空谢谢认可

博客简介

码云笔记 mybj123.com,一个专注Web前端开发技术的博客,主要记录和总结博主在前端开发工作中常用的实战技能及前端资源分享,分享各种科普知识和实用优秀的代码,以及分享些热门的互联网资讯和福利!码云笔记有你更精彩!
更多博客详情请看关于博客

精彩评论

站点统计

  • 文章总数: 472 篇
  • 分类数目: 13 个
  • 独立页面: 8 个
  • 评论总数: 228 条
  • 链接总数: 15 个
  • 标签总数: 1036 个
  • 建站时间: 522 天
  • 访问总量: 8681278 次
  • 最近更新: 2019年11月18日