自定义加载条

在页面加载前新增 loading 状态的几种方式

loading 加载分为好几种,一种是含百分比计算的,一种是不含百分比。
含百分比的需要进行计算,有的网站是通过定义不同的节点来进行计算,比如执行了一个 ajax 结束算一个节点,进度条增加百分之三十,再执行完一个再加百分之三十。这个方法我自己也没有去实际做过,只是查资料了解到的,所以本文对此不作介绍。
不含百分比的就比较简单,只需要放一个动画就可以。

先记录一下基本步骤

  1. 将 loading 页和主页面分开加载,因为所有的文件在主页面都打包成了一个 js 文件,所以单独将 loading 拿出来加载,处理方式是修改 webpack 打包文件
 entry: {     
      main: './main/index.js', // 原本的主页面文件     
     loading: './loading/index.js', // 新增的 loading 页面文件   
},
  1. 在 index.html 文件中,引入 loading.js 文件,引入的文件一定要放在 main.js 之前,因为要让浏览器先加载 loading 文件
<body> 
    <main id="application-container"></main>   <!--在 main.js 之前引入 loading.js 文件-->  
    <script src="/demo/static/apps/entry/loading.js"></script>   
    <script src="/demo/static/apps/entry/main.js"></script>
</body>
  1. 编辑 loading.js 文件内容,这才是重点的地方
    我们的想法是先加载 loading 的动画,当检测到 dom 已经加载完毕以后,移除掉 loading 动画,加载主页面
    此处需要下载 document-ready 库用于检测 document.ready 事件。
import ready from 'document-ready';
const loader = document.createElement('div');
const body = document.getElementsByTagName('body')[0] 
const progress = '<div>正在加载啦啦啦啦</div>'; // loading 页内容
loader.innerHTML = progress; body.appendChild(loader) 
// 上面的内容基本就是在做一件事,就是创建新元素插入到 body 中
ready(() => {
 // 当 document.ready 时,移除元素 
body.removeChild(loader)
})

基本的步骤就是上述部分,但是很多时候我们并不希望只是一个简陋的元素展示出来,希望有加载条或者一些动画等等。下面分三种情况说明一下。

loading 动画

  1. 动图
    直接使用 gif 其实是最简单的部分,用 gif 替代普通的元素即可,如
    const progress = <div>正在加载啦啦啦啦![](demo.gif)</div>;
    再加一些样式即可,其实如果 dom 元素太多的话,可以另用一个文件去专门写布局和样式,然后再导入到 loading.js 中。

  2. 含百分比加载条,现成的轮子:pace.js,可以直接下载 pace.js 以及它的主题,然后在 html 中引入,官网上写得很清楚了。另外一种方式是 npm 下载了,这里有两个地方要注意。

    • 下载的包名并不是 pace,而是 pace-js,yarn add pace-js 下载的才是正确的包
    • 引入 pace 模块的时候有 bug,无法直接通过 import pace from 'pace-js' 引入 pace module,原因是 pace.js 中的 AMD define 时出错了,它将 pace 定义为依赖,但是 pace 在 npm 中是另外的一个不关联 CLI 进度条包的库,也就是说和这个库没有什么关系,具体解决方法:
      在 webpack 中新增下面这条语句
{ 
  test: require.resolve("pace-progress"), 
  loader: "imports?define=>false" 
}

下载 imports-loader 包:yarn add imports-loader,然后就解决了。

原因和解决方法都是参考这个 issue:[我是解决问题的 issue](https://github.com/HubSpot/pace/issues/328)

解决这些以后,就可以直接使用 pace 了,但是一定要记得进入 pace 的样式包,当然也可以自己写,根据以下的 class 写自己指定的样式,也可以直接使用 pace 文档中已有的样式。

<div class="pace pace-inactive">
  <div class="pace-progress" data-progress-text="100%" data-progress="99" style="transform: translate3d(17%, 0px, 0px);"> 
  <div class="pace-progress-inner" style="   background: black;">
</div>
</div>
  <div class="pace-activity"></div>
</div>

pace.start() 开始加载进度条,pace.stop() 则停止加载,它没有 done 方法,凡事可以监听 done 事件,在加载执行完成时触发的事件,方法如下:

 pace.on("done",function(){ 
  console.log('im done!');
})

使用中遇到的问题:使用 pace 的过程中发现一个问题,pace 执行 stop() 时貌似是异步的,如果将 pace.stop() 放入 ready(){} 中执行,loading 页面的加载条还未结束,或者结束还未消失,主页面已经出现,导致加载条覆盖住了主页面。所以也许 pace 的用法是需要增加一个 mask 遮罩层或者仅仅用在 ajax 上比较合理?(虽然不仅仅能用在 ajax 上)。

  1. 使用 nprogress
    nprogress 类似于 pace,但是没有出现 pace 出现的上述多个问题,而且它没有自带主题,貌似只有一个固有样式,但是我们仍然可以对它进行自定义。
    用法如下:
  • yarn add nprogress

  • 引入 Nprogress 模块,也要记得引入样式

import NProgress from 'nprogress';
import 'nprogress/nprogress.css'; 

在需要的地方执行 Nprogress.start() 开始加载进度条,在任何需要的地方执行 Nprogress.done() 结束进度条,展示出来的效果就是它的默认样式了。

我们可以对它的样式进行自定义,或者干脆对它的DOM元素进行自定义,它原本的结构如下:

<div id="nprogress"> 
  <div class="bar" role="bar" style="transform: translate3d(-73.2731%, 0px, 0px); transition: all 200ms ease;">   
    <div class="peg"></div> 
  </div> 
  <div class="spinner" role="spinner">   
    <div class="spinner-icon"></div> 
  </div>
</div>

通过以上结构是默认结构,我们可以自己写一份 css,然后引入到 loading/index.js 文件当中。
或者可以通过以下方式自定义结构,

const progress = `<div id="nprogress">
<div class="bar" role="bar" style="background: red; transform: translate3d(-0.6%, 0px, 0px); transition: all 200ms ease;">
<div class="peg" style="box-shadow: 0 0 10px #fff, 0 0 5px #fff;"></div>
</div>
<div class="spinner" role="spinner">
<div class="spinner-icon" style="border-top-color:white;border-left-color: white"></div>
</div>
</div>`;
NProgress.configure({  template: progress, });

这只是一个例子,progress 的内容可以单独作为一个文件,再 import 进来,需要注意几个地方:
configure 顾名思义是对 Nprogress 进行设置,所以要放在 Nprogress.start() 之前。

在自定义结构时,要给一些元素指定role属性,这个是必须要指定的,不然 nprogress 不清楚哪个元素该做什么。比如:

role="bar" //表示的是加载条
role="spinner" //表示的是原本样式中右上角的旋转,具体叫什么我也说不上来...

在本处,我们就通过如下方式来进行:

// loading/index.js
import NProgress from 'nprogress'; // 引入 Nprogress 模块
import progress from './demo/index'; // 自定义的 dom
NProgress.configure({ 
// 设置自己定义的dom
 template: progress,});
    NProgress.start(); // 加载进度条
ready(() => { 
    NProgress.done(); // 结束并移除进度条
})

progress 同样遇到 pace 一样的问题,即 loading 内容还没消失,主页面内容就已经显示了,document.ready 的节点执行 nprogress.done() 的操作,首先滚动条到滚动到达最底的位置,然后再让 loading 消失,这几个步骤需要一定的时间,所以会出现这种情况。pace 刚才的问题应该同样是这个原因。只能让 template 尽量简洁,减少渲染时间。
我个人更倾向于用 nprogress。如果喜欢 pace 的主题又想用 progress 的,可以直接去参考样式,内容并不多,毕竟两者的 dom 结构比较相似,样式名换一下再稍微修改修改应该就能用起来。

当然如果想要更多自己定制的内容,还是需要去看 pace 或者 progress 官网,链接如下:
pace
progress

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,980评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,178评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,868评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,498评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,492评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,521评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,910评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,569评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,793评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,559评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,639评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,342评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,931评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,904评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,144评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,833评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,350评论 2 342

推荐阅读更多精彩内容