jquery弹窗插件dialog_jquery进度条插件

jquery弹窗插件dialog_jquery进度条插件143行js顶部进度条最小插件-nanobar.js源码解析

大家好,又见面了,我是你们的朋友全栈君。

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

/* 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 进度条移动的方法
nanobar nanobar对象,它将在new构造函数时作为结果返回

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

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

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

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

var nanobar = new Nanobar();
nanobar.go(80);
复制代码

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

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

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

  1. addCss方法,为head节点内增加<style id="nanobarcss">节点,并把上文的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 与终点相比的距离

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

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

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

另外,引用作者原话:

Nanobar injects a style tag in your HTML head. Bar divs has class .bar, and its containers .nanobar, so you can overwrite its values. You should know what to do with that ;)

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/107246.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • oracle中拼接字符串_oracle 连接字符串

    oracle中拼接字符串_oracle 连接字符串1.listagg   该方法拼接后是varchar2类型,有最大长度限制,在OracleDatabase中,VARCHAR2字段类型,最大值为4000;PL/SQL中VARCHAR2变量类型,最大字节长度为32767。   适用场景:当要拼接的字符较少时使用。select’select’||col||’from’||table_name||’;’…

  • SIGABRT错误的调试办法[通俗易懂]

    iOS经常会遇到一个头疼的error就是在main函数上显示“Thread1:signalSIGABRT”这个错误,终于在stackoverflow上找到了调试的办法: 原文链接:http://stackoverflow.com/questions/9782621/i-have-an-error-in-main-m-thread-1-signal-sigabrt-how

  • Spring Cloud的架构[通俗易懂]

    Spring Cloud的架构[通俗易懂]SpringCloud架构图Eureka用于服务注册和发现,利用了客户端的服务发现,所以它内部需要Ribbon作为客户端负载均衡。Hystrix,客户端容错保护,服务熔断、请求缓存、请求合并、依赖隔离。Feign,声明式服务调用。Bus,消息总线,配合Config仓库修改的一种Stream实现,Dashboard,Hystrix仪表盘,监控集群模式和单点模式,其中集群模式…

  • QQ农场怎么开挂_qq农场矿山辅助

    QQ农场怎么开挂_qq农场矿山辅助很久没更新博客了,今天就拿开发QQ开心农场外挂的一些问题来写篇短日志充个数。 关于登陆       在web上,QQ登陆的时候是将密码加密后再提交了,打开http://xiaoyou.qq.com,找到了密码加密过程在http://imgcache.qq.com/campus/js/Mlogin.js 文件中,通过解读代码可以了解到,QQ一共进行了4次的MD5运算,具体过程如下:比如

  • matlab插值实验目的,matlab插值实验报告数学实验.doc

    matlab插值实验目的,matlab插值实验报告数学实验.docmatlab插值实验报告数学实验.doc新乡学院数学与信息科学系实验报告实验项目名称插值实验所属课程名称数学实验实验类型综合性实验实验日期班级学号姓名成绩一、实验概述【实验目的】掌握用MATLAB插值的方法,了解拉格朗日插值、线性插值、样条插值的基本思想,了解三种网格节点数据的插值方法的基本思想,了解掌握用MATLAB计算一维差值和二维插值的方法。【实验原理】拉格朗日LAGRANGE插值。已知函…

  • 101道算法javaScript描述【一】

    101道算法javaScript描述【一】数据结构与算法是计算机专业必修课,但是对于前端工程师来说,沉浸在业务代码之中很少会和算法直接打交道,甚于说根本不需要用到什么算法。那么我们为什么要学习算法,意义何在?不会算法活不是一样能干。把一件事情做到极致是非常必要的职业心态,这离不开数据结构和算法。另一方面,再说面试,这和在学生时代为什么要学数理化是一个道理,考试要考,你就要学。面试造火箭,工作拧螺丝,面试官通过问几道算法题了解你的编程和逻辑思维能力并不奇怪。万丈高楼平地起,基础知识掌握多少,一定程度上决定了我们的技术能走多远。想要作出一点事情,基础一

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号