progressJS.js 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  1. ;(function(window) {
  2. //创建滑块构造函数
  3. function Progress(
  4. target,
  5. {
  6. size = 10,
  7. val = 0,
  8. precision = 0,
  9. getVal = () => {},
  10. drag = true,
  11. direction = 'horizontal',
  12. tip = false
  13. } = {}
  14. ) {
  15. if (!target) return alert('必须指定实例对象的容器!')
  16. //指定实例容器
  17. this.container = document.querySelector(target)
  18. this.size = size
  19. this.val = val
  20. this.precision = precision
  21. this.getVal = getVal
  22. this.drag = drag
  23. this.direction = direction
  24. if (typeof tip === 'object') {
  25. this.tip = tip || {
  26. trigger: 'show', // hover
  27. align: 'top' // bottom
  28. }
  29. } else if (typeof tip != 'boolean') {
  30. return alert('tip配置错误')
  31. }
  32. this.initialize()
  33. }
  34. Progress.prototype = {
  35. constructor: Progress,
  36. //初始化
  37. initialize: function() {
  38. if (
  39. this.size < 0 ||
  40. this.val < 0 ||
  41. this.val > 100 ||
  42. this.precision < 0 ||
  43. this.precision > 4 ||
  44. (this.direction != 'horizontal' && this.direction != 'vertical') ||
  45. !this.container ||
  46. (typeof this.drag != 'boolean' && typeof this.drag != 'object')
  47. )
  48. return alert('参数配置错误!')
  49. //调用渲染
  50. this.rander()
  51. this.renderLine()
  52. },
  53. //渲染方法
  54. rander: function() {
  55. this.bgBar = document.createElement('div')
  56. this.bgLine = document.createElement('div')
  57. this.btnTip = document.createElement('div')
  58. const { bgBar, container, bgLine, btnTip } = this
  59. //渲染bgBar
  60. switch (this.direction) {
  61. case 'horizontal':
  62. bgBar.classList.add('ProgressBar')
  63. bgBar.style.height = this.size + 'px'
  64. bgBar.style.width = 100 + '%'
  65. bgBar.style.borderRadius = this.size / 2 + 'px'
  66. //添加btn
  67. bgLine.appendChild(btnTip)
  68. break
  69. case 'vertical':
  70. bgBar.classList.add('ProgressBar')
  71. bgBar.style.width = this.size + 'px'
  72. bgBar.style.height = 100 + '%'
  73. bgBar.style.borderRadius = this.size / 2 + 'px'
  74. //添加btn
  75. btnTip.classList.add('vertical')
  76. bgLine.appendChild(btnTip)
  77. break
  78. }
  79. //渲染btn
  80. btnTip.classList.add('btn')
  81. btnTip.style.width = this.size + 'px'
  82. btnTip.style.height = this.size + 'px'
  83. //渲染bgLine
  84. bgLine.classList.add('ProgressLine')
  85. bgLine.style.borderRadius = this.size / 2 + 'px'
  86. bgBar.appendChild(bgLine)
  87. container.appendChild(bgBar)
  88. //是否开启拖拽
  89. if (this.drag) {
  90. this.Dragdrop()
  91. } else {
  92. this.btnTip.classList.add('disable')
  93. }
  94. //是否开启tip
  95. if (this.tip || typeof this.tip === 'object') this.openTip()
  96. //开启loading
  97. this.onLoading()
  98. },
  99. //拖拽方法
  100. Dragdrop: function() {
  101. const bgBar = this.bgBar
  102. const mothes = e => {
  103. // e.preventDefault()
  104. // e.stopPropagation()
  105. this.getPos(e)
  106. }
  107. bgBar.addEventListener('mousedown', e => {
  108. document.addEventListener('mousemove', mothes)
  109. this.getPos(e)
  110. })
  111. document.addEventListener('mouseup', e => {
  112. document.removeEventListener('mousemove', mothes)
  113. })
  114. bgBar.addEventListener('touchstart', e => {
  115. document.addEventListener('touchmove', mothes)
  116. this.getPos(e)
  117. })
  118. document.addEventListener('touchend', e => {
  119. document.removeEventListener('touchmove', mothes)
  120. })
  121. },
  122. //获取鼠标位置事件
  123. getPos: function(event) {
  124. if (typeof event.touches === 'undefined') {
  125. event.preventDefault()
  126. event.stopPropagation()
  127. }
  128. if (event.touches) event = event.touches[0]
  129. this.oldVal = this.val
  130. switch (this.direction) {
  131. case 'horizontal':
  132. let clX = event.clientX + this.size / 2 //鼠标X轴位置
  133. let bgBarW = this.bgBar.clientWidth //bgbar宽度
  134. let bgBarLeft = this.getElementLeft(this.bgBar)
  135. this.val =
  136. ((clX - bgBarLeft - this.size) / (bgBarW - this.size)) * 100
  137. break
  138. case 'vertical':
  139. let clY = event.clientY + this.size / 2 //鼠标X轴位置
  140. let bgBarH = this.bgBar.clientHeight //bgbar宽度
  141. let bgBarTop = this.getElementTop(this.bgBar)
  142. this.val =
  143. 100 - ((clY - bgBarTop - this.size) / (bgBarH - this.size)) * 100
  144. break
  145. }
  146. this.val = Math.max(0, this.val)
  147. this.val = Math.min(100, this.val)
  148. this.renderLine()
  149. this.eventVal()
  150. },
  151. //获取元素距离屏幕左端的位置
  152. getElementLeft: function(element) {
  153. let { offsetLeft, offsetParent } = element
  154. while (offsetParent !== null) {
  155. offsetLeft += offsetParent.offsetLeft
  156. offsetParent = offsetParent.offsetParent
  157. }
  158. return offsetLeft
  159. },
  160. //获取元素距离屏幕上端的位置
  161. getElementTop: function(element) {
  162. let { offsetTop, offsetParent } = element
  163. while (offsetParent !== null) {
  164. offsetTop += offsetParent.offsetTop
  165. offsetParent = offsetParent.offsetParent
  166. }
  167. return offsetTop
  168. },
  169. //渲染line宽度
  170. renderLine: function() {
  171. switch (this.direction) {
  172. case 'horizontal':
  173. this.bgLine.style.width =
  174. ((this.bgBar.clientWidth - this.size) * this.val) / 100 +
  175. this.size +
  176. 'px'
  177. break
  178. case 'vertical':
  179. this.bgLine.style.height =
  180. ((this.bgBar.clientHeight - this.size) * this.val) / 100 +
  181. this.size +
  182. 'px'
  183. break
  184. }
  185. },
  186. //获取默认值
  187. eventVal: function() {
  188. this.val = +this.val.toFixed(this.precision)
  189. if (this.oldVal === this.val) {
  190. return
  191. }
  192. // this.val = this.val
  193. // console.log(this.val)
  194. this.getVal && this.getVal(this)
  195. if (this.tip || typeof this.tip === 'object')
  196. this.tipBox.innerText = `${this.val}%`
  197. },
  198. //更新默认值
  199. updateVal: function(res) {
  200. if (res < 0 || res > 100) return
  201. this.val = +res
  202. this.renderLine()
  203. this.val = +res.toFixed(this.precision)
  204. if (this.tip || typeof this.tip === 'object')
  205. this.tipBox.innerText = `${this.val}%`
  206. },
  207. //开启tip
  208. openTip: function() {
  209. //console.log(this)
  210. const btnTip = this.btnTip
  211. this.tipBox = document.createElement('span')
  212. this.tipBox.classList.add('progressVal')
  213. this.tipBox.innerText = `${this.val}%`
  214. btnTip.appendChild(this.tipBox)
  215. this.tip.trigger && this.tipConfig()
  216. },
  217. //配置tip
  218. tipConfig: function() {
  219. //console.log(this.tip.trigger)
  220. switch (this.tip.trigger) {
  221. case 'hover':
  222. this.tipBox.style.opacity = 0
  223. this.bgBar.addEventListener(
  224. 'mouseenter',
  225. () => (this.tipBox.style.opacity = 1)
  226. )
  227. this.bgBar.addEventListener(
  228. 'mouseleave',
  229. () => (this.tipBox.style.opacity = 0)
  230. )
  231. this.bgBar.addEventListener(
  232. 'touchstart',
  233. () => (this.tipBox.style.opacity = 1)
  234. )
  235. this.bgBar.addEventListener(
  236. 'touchend',
  237. () => (this.tipBox.style.opacity = 0)
  238. )
  239. break
  240. case 'show':
  241. this.tipBox.style.opacity = 1
  242. break
  243. }
  244. switch (this.tip.align) {
  245. case 'bottom':
  246. this.tipBox.classList.add('bottom')
  247. break
  248. case 'left':
  249. this.tipBox.classList.add('left')
  250. break
  251. case 'right':
  252. this.tipBox.classList.add('right')
  253. break
  254. }
  255. },
  256. //开启Loading
  257. onLoading: function() {
  258. this.btnLoading = document.createElement('span')
  259. const { btnLoading, btnTip } = this
  260. btnLoading.classList.add('loading')
  261. btnTip.appendChild(btnLoading)
  262. btnLoading.style.width = btnTip.offsetWidth/2 + 'px'
  263. btnLoading.style.height = btnTip.offsetHeight/2 + 'px'
  264. },
  265. onLoad: function(e, callback = () => {}) {
  266. if (typeof e !== 'boolean') return alert('onload配置错误')
  267. if (e) this.btnLoading.style.display = 'block'
  268. callback(this)
  269. }
  270. }
  271. window.Progress = Progress
  272. })(window)