溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

js頂部進度條最小插件nanobar.js如何實現(xiàn)

發(fā)布時間:2021-11-23 11:43:10 來源:億速云 閱讀:115 作者:小新 欄目:開發(fā)技術

這篇文章主要介紹js頂部進度條最小插件nanobar.js如何實現(xiàn),文中介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們一定要看完!

網(wǎng)頁頂部進度條插件的有四五種,基本原理就是動態(tài)地創(chuàng)建一個元素,然后通過設置它的width來實現(xiàn)動畫效果,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內(nèi)容來看,僅有.bar有transition:height .3s的過渡設置,height過渡發(fā)生的時間應該是被刪除時。在橫向應該是沒有動畫效果,但是從官網(wǎng)演示效果來看,橫向仍然有一定的動畫效果,這個問題下面會提到。

構(gòu)造函數(shù)NanoBar

NanoBar接受一個opts作為參數(shù),文檔記載的opts詳細內(nèi)容如下:

名稱功能
id指定nanobar的id
classname指定nanobar的class
target指定Nanobar的表示位置,一般對于做頂部進度條來說不到。值得一提的是,這個參數(shù)類型為DOM Element,你必須使用document.getxxxxx之類的方法為其賦值。

首先聲明了三個變量:

名稱描述
el這就是動態(tài)創(chuàng)建的元素-一個既沒有ID也沒有Class的空div
applyGo進度條移動的方法
nanobarnanobar對象,它將在new構(gòu)造函數(shù)時作為結(jié)果返回

其中,nanobar包含這兩個元素:

名稱描述
el上面動態(tài)創(chuàng)建的元素
go對外開放的方法,參數(shù)為數(shù)值,那么它肯定代表了百分比而不是像素等實際物理單位

此處的go處理內(nèi)實質(zhì)上調(diào)用的是applyGo,而applyGo此時肯定為undefined,所以applyGo實際上在別處賦值。這樣處理的結(jié)果,相當于是一層封裝,隱藏了內(nèi)部實際的go方法內(nèi)容。

另外也可以得出nanobar的最簡單的使用方法:

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

接下來,聲明了兩個內(nèi)部函數(shù),這兩個內(nèi)部函數(shù)可以訪問上面提到的三個變量:

名稱作用
rm用于進度完成后,刪除動態(tài)創(chuàng)建的元素
init初始化方法,這個需要重點關注

然后是一些必要處理,由這三個部分組成:

  1. addCss方法,為head節(jié)點內(nèi)增加&lt;style id="nanobarcss"&gt;節(jié)點,并把上文的css填入其中。

  2. 調(diào)用addClass方法,創(chuàng)建類名為nanobar的容器。需要注意的是,相比于直接操作className方法內(nèi)調(diào)用了HTML5的新APIclassList,使用它可以像jquery的addClass、removeClass一樣方便的對dom對象的class進行增加刪除判斷。更多信息請看這里。

  3. 接下來是對opts參數(shù)進行處理:
    主要是為el元素賦予id和className,根據(jù)是否指定了父容器,也就是target,改變?nèi)萜鞯膒osition,并且最終將它插入到對應的位置上。

接著來看init()方法:

前面所有的操作,創(chuàng)建了一個名為nanobar的容器,接下來就該創(chuàng)建bar主體了。

可以看到,bar變量內(nèi)仍然和nanobar一樣,由elgo兩部分組成,go最終將被賦值到外層容器的applyGo,el將被作為子元素插入到外層容器的el內(nèi)。

這樣,當用最簡單的方式調(diào)用go時,它的順序就是這樣的:

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


調(diào)用了go方法后,為什么橫向會有一定的動畫效果呢?

觀察一下nanobar的動作方法gomove、place
其中的控制量有這么幾個:

名稱作用
on相當于布爾flag,標識了進度是否完成了
here終點位置
dist與終點相比的距離

實際處理流程可以這樣表示:

js頂部進度條最小插件nanobar.js如何實現(xiàn)

形成動畫的根本原因則是這么兩個原因:

  1. 方法place(width - dist / 4)對剩余空間的細分

  2. 第58緊隨其后的setTimeout(go,16),假設把x軸看成是16ms,把Y軸看成是每次細分的長度,將會得到一個圖像類似于log2x(前期趨勢大,后期趨勢平穩(wěn),類似于動畫函數(shù)中的ease-out)的表達式。

以上是“js頂部進度條最小插件nanobar.js如何實現(xiàn)”這篇文章的所有內(nèi)容,感謝各位的閱讀!希望分享的內(nèi)容對大家有幫助,更多相關知識,歡迎關注億速云行業(yè)資訊頻道!

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI