温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

js顶部进度条最小插件nanobar.js如何实现

发布时间:2021-11-23 11:43:10 来源:亿速云 阅读:116 作者:小新 栏目:开发技术

这篇文章主要介绍js顶部进度条最小插件nanobar.js如何实现,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!

网页顶部进度条插件的有四五种,基本原理就是动态地创建一个元素,然后通过设置它的width来实现动画效果,width增长到达指定位置时,将其去掉。

/* http://nanobar.micronube.com/  ||  https://github.com/jacoborus/nanobar/    MIT LICENSE */
(function (root) {
  'use strict'
  // container styles
  var css = '.nanobar{width:100%;height:4px;z-index:9999;top:0}.bar{width:0;height:100%;transition:height .3s;background:#000}'

  // add required css in head div
  function addCss () {
    var s = document.getElementById('nanobarcss')

    // check whether style tag is already inserted
    if (s === null) {
      s = document.createElement('style')
      s.type = 'text/css'
      s.id = 'nanobarcss'
      document.head.insertBefore(s, document.head.firstChild)
      // the world
      if (!s.styleSheet) return s.appendChild(document.createTextNode(css))
      // IE
      s.styleSheet.cssText = css
    }
  }

  function addClass (el, cls) {
    if (el.classList) el.classList.add(cls)
    else el.className += ' ' + cls
  }

  // create a progress bar
  // this will be destroyed after reaching 100% progress
  function createBar (rm) {
    // create progress element
    var el = document.createElement('div'),
        width = 0,
        here = 0,
        on = 0,
        bar = {
          el: el,
          go: go
        }

    addClass(el, 'bar')

    // animation loop
    function move () {
      var dist = width - here

      if (dist < 0.1 && dist > -0.1) {
        place(here)
        on = 0
        if (width === 100) {
          el.style.height = 0
          setTimeout(function () {
            rm(el)
          }, 300)
        }
      } else {
        place(width - dist / 4)
        setTimeout(go, 16)
      }
    }

    // set bar width
    function place (num) {
      width = num
      el.style.width = width + '%'
    }

    function go (num) {
      if (num >= 0) {
        here = num
        if (!on) {
          on = 1
          move()
        }
      } else if (on) {
        move()
      }
    }
    return bar
  }

  function Nanobar (opts) {
    opts = opts || {}
    // set options
    var el = document.createElement('div'),
        applyGo,
        nanobar = {
          el: el,
          go: function (p) {
            // expand bar
            applyGo(p)
            // create new bar when progress reaches 100%
            if (p === 100) {
              init()
            }
          }
        }

    // remove element from nanobar container
    function rm (child) {
      el.removeChild(child)
    }

    // create and insert progress var in nanobar container
    function init () {
      var bar = createBar(rm)
      el.appendChild(bar.el)
      applyGo = bar.go
    }

    addCss()

    addClass(el, 'nanobar')
    if (opts.id) el.id = opts.id
    if (opts.classname) addClass(el, opts.classname)

    // insert container
    if (opts.target) {
      // inside a div
      el.style.position = 'relative'
      opts.target.insertBefore(el, opts.target.firstChild)
    } else {
      // on top of the page
      el.style.position = 'fixed'
      document.getElementsByTagName('body')[0].appendChild(el)
    }

    init()
    return nanobar
  }

  if (typeof exports === 'object') {
    // CommonJS
    module.exports = Nanobar
  } else if (typeof define === 'function' && define.amd) {
    // AMD. Register as an anonymous module.
    define([], function () { return Nanobar })
  } else {
    // Browser globals
    root.Nanobar = Nanobar
  }
}(this))

大体看下来,这个插件有这样几个特点:

  • dom+js原生选择器

  • 支持模块化

  • es5+IIFE

  • 不用分号派

详细来看:

在程序的开头,定义了必要的Css属性,包括bar(主体)和Nanobar(容器)两个class:

.nanobar{
width:100%;
height:4px;
z-index:9999;
top:0
}

.bar{
width:0;
height:100%;
transition:height .3s;
background:#000
}

从css内容来看,仅有.bar有transition:height .3s的过渡设置,height过渡发生的时间应该是被删除时。在横向应该是没有动画效果,但是从官网演示效果来看,横向仍然有一定的动画效果,这个问题下面会提到。

构造函数NanoBar

NanoBar接受一个opts作为参数,文档记载的opts详细内容如下:

名称功能
id指定nanobar的id
classname指定nanobar的class
target指定Nanobar的表示位置,一般对于做顶部进度条来说不到。值得一提的是,这个参数类型为DOM Element,你必须使用document.getxxxxx之类的方法为其赋值。

首先声明了三个变量:

名称描述
el这就是动态创建的元素-一个既没有ID也没有Class的空div
applyGo进度条移动的方法
nanobarnanobar对象,它将在new构造函数时作为结果返回

其中,nanobar包含这两个元素:

名称描述
el上面动态创建的元素
go对外开放的方法,参数为数值,那么它肯定代表了百分比而不是像素等实际物理单位

此处的go处理内实质上调用的是applyGo,而applyGo此时肯定为undefined,所以applyGo实际上在别处赋值。这样处理的结果,相当于是一层封装,隐藏了内部实际的go方法内容。

另外也可以得出nanobar的最简单的使用方法:

var nanobar = new Nanobar();
nanobar.go(80);

接下来,声明了两个内部函数,这两个内部函数可以访问上面提到的三个变量:

名称作用
rm用于进度完成后,删除动态创建的元素
init初始化方法,这个需要重点关注

然后是一些必要处理,由这三个部分组成:

  1. addCss方法,为head节点内增加&lt;style id="nanobarcss"&gt;节点,并把上文的css填入其中。

  2. 调用addClass方法,创建类名为nanobar的容器。需要注意的是,相比于直接操作className方法内调用了HTML5的新APIclassList,使用它可以像jquery的addClass、removeClass一样方便的对dom对象的class进行增加删除判断。更多信息请看这里。

  3. 接下来是对opts参数进行处理:
    主要是为el元素赋予id和className,根据是否指定了父容器,也就是target,改变容器的position,并且最终将它插入到对应的位置上。

接着来看init()方法:

前面所有的操作,创建了一个名为nanobar的容器,接下来就该创建bar主体了。

可以看到,bar变量内仍然和nanobar一样,由elgo两部分组成,go最终将被赋值到外层容器的applyGoel将被作为子元素插入到外层容器的el内。

这样,当用最简单的方式调用go时,它的顺序就是这样的:

容器nanobar.go => applyGo => 本体bar.go


调用了go方法后,为什么横向会有一定的动画效果呢?

观察一下nanobar的动作方法gomoveplace
其中的控制量有这么几个:

名称作用
on相当于布尔flag,标识了进度是否完成了
here终点位置
dist与终点相比的距离

实际处理流程可以这样表示:

js顶部进度条最小插件nanobar.js如何实现

形成动画的根本原因则是这么两个原因:

  1. 方法place(width - dist / 4)对剩余空间的细分

  2. 第58紧随其后的setTimeout(go,16),假设把x轴看成是16ms,把Y轴看成是每次细分的长度,将会得到一个图像类似于log2x(前期趋势大,后期趋势平稳,类似于动画函数中的ease-out)的表达式。

以上是“js顶部进度条最小插件nanobar.js如何实现”这篇文章的所有内容,感谢各位的阅读!希望分享的内容对大家有帮助,更多相关知识,欢迎关注亿速云行业资讯频道!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI