美文网首页
自定义加载条

自定义加载条

作者: 吃柠檬的刺猬 | 来源:发表于2017-07-03 14:54 被阅读0次

    在页面加载前新增 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

    相关文章

      网友评论

          本文标题:自定义加载条

          本文链接:https://www.haomeiwen.com/subject/dhuacxtx.html