cupload.js 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366
  1. (function(window, document) {
  2. var Cupload = function(options) {
  3. if (!(this instanceof Cupload)) {
  4. return new Cupload(options)
  5. }
  6. this.localValue = {
  7. ele: '#cupload',
  8. name: 'image',
  9. num: 1,
  10. width: 148,
  11. height: 148,
  12. }
  13. this.opt = this.extend(this.localValue, options, true)
  14. this.i = 0;
  15. this.imageBox = new Array();
  16. this.imagePreview = new Array();
  17. this.imageInput = new Array();
  18. this.imageDelete = new Array();
  19. this.deleteBtn = new Array();
  20. if ((typeof options.ele) === "string") {
  21. this.opt.ele = document.querySelector(options.ele)
  22. } else {
  23. this.opt.ele = options.ele
  24. }
  25. this.initDom();
  26. }
  27. Cupload.prototype = {
  28. constructor: this,
  29. initDom: function() {
  30. this.cteateImageList()
  31. this.createUploadBox()
  32. if (this.opt.data) {
  33. this.showImagePreview()
  34. }
  35. },
  36. extend: function(o, n, override) {
  37. for (var key in n) {
  38. if (n.hasOwnProperty(key) && (!o.hasOwnProperty(key) || override)) {
  39. o[key] = n[key]
  40. }
  41. }
  42. return o
  43. },
  44. cteateImageList: function() {
  45. this.imageList = document.createElement('ul')
  46. this.imageList.className = 'cupload-image-list'
  47. this.imageList.style.margin = 0
  48. this.imageList.style.padding = 0
  49. this.imageList.style.display = 'inline'
  50. this.imageList.style.verticalAlign = 'top'
  51. this.imageList.style.minHeight = this.opt.height
  52. this.opt.ele.appendChild(this.imageList)
  53. },
  54. createUploadBox: function() {
  55. this.uploadBox = document.createElement('div')
  56. this.uploadBox.className = 'cupload-upload-box'
  57. this.uploadBox.style.position = 'relative'
  58. this.uploadBox.style.display = 'inline-block'
  59. this.uploadBox.style.textAlign = 'center'
  60. this.uploadBox.style.backgroundColor = '#fbfdff'
  61. this.uploadBox.style.border = '1px dashed #c0ccda'
  62. this.uploadBox.style.borderRadius = '6px'
  63. this.uploadBox.style.WebkitBoxSizing = 'border-box'
  64. this.uploadBox.style.boxSizing = 'border-box'
  65. this.uploadBox.style.width = this.opt.width + 'px'
  66. this.uploadBox.style.height = this.opt.height + 'px'
  67. this.uploadBox.style.lineHeight = this.opt.height - 2 + 'px'
  68. this.opt.ele.appendChild(this.uploadBox)
  69. this.createUploadBtn()
  70. this.createUploadInput()
  71. var _this = this
  72. this.uploadBox.onmouseover = function() {
  73. _this.uploadBox.style.borderColor = '#409eff'
  74. }
  75. this.uploadBox.onmouseout = function() {
  76. _this.uploadBox.style.borderColor = '#c0ccda'
  77. }
  78. },
  79. createUploadBtn: function() {
  80. this.uploadBtn = document.createElement('span')
  81. this.uploadBtn.className = 'cupload-upload-btn'
  82. this.uploadBtn.style.fontSize = '28px'
  83. this.uploadBtn.style.color = '#8c939d'
  84. this.uploadBtn.innerHTML = '+'
  85. this.uploadBox.appendChild(this.uploadBtn)
  86. },
  87. createUploadInput: function() {
  88. this.uploadInput = document.createElement('input')
  89. this.uploadInput.className = 'cupload-upload-input'
  90. this.uploadInput.style.position = 'absolute'
  91. this.uploadInput.style.top = 0
  92. this.uploadInput.style.right = 0
  93. this.uploadInput.style.width = '100%'
  94. this.uploadInput.style.height = '100%'
  95. this.uploadInput.style.opacity = 0
  96. this.uploadInput.style.cursor = 'pointer'
  97. this.uploadInput.type = 'file'
  98. this.uploadInput.multiple = 'multiple'
  99. this.uploadInput.accept = 'image/*'
  100. this.uploadInput.title = ''
  101. this.uploadBox.appendChild(this.uploadInput)
  102. var _this = this
  103. this.uploadInput.onchange = function() {
  104. _this.removeUploadBox()
  105. _this.uploadImage()
  106. }
  107. },
  108. uploadImage: function() {
  109. var file = this.uploadInput.files[0]
  110. this.createUploadBox()
  111. if (!file || this.limitedSize(file)) {
  112. return false;
  113. }
  114. var reader = new FileReader();
  115. var _this = this
  116. reader.onload = function(e) {
  117. _this.limitedWidthAndHeight(e.target.result, file.name)
  118. }
  119. reader.readAsDataURL(file);
  120. },
  121. limitedSize: function(file) {
  122. if (this.opt.minSize && file.size < this.opt.minSize * 1024) {
  123. alert('图片大小未到最小限制')
  124. return true
  125. }
  126. if (this.opt.maxSize && file.size > this.opt.maxSize * 1024) {
  127. alert('图片大小超出最大限制')
  128. return true
  129. }
  130. if (this.opt.limitedSize && file.size > this.opt.limitedSize * 1024) {
  131. alert('图片大小不符合要求')
  132. return true
  133. }
  134. return false
  135. },
  136. limitedWidthAndHeight: function(src, name) {
  137. var tempImage = new Image()
  138. tempImage.src = src
  139. var _this = this
  140. tempImage.onload = function() {
  141. if (_this.opt.minWidth && this.width < _this.opt.minWidth) {
  142. alert('图片宽度未到最小限制')
  143. return false
  144. }
  145. if (_this.opt.minHeight && this.height < _this.opt.minHeight) {
  146. alert('图片高度未到最小限制')
  147. return false
  148. }
  149. if (_this.opt.maxWidth && this.width > _this.opt.maxWidth) {
  150. alert('图片宽度超出最大限制')
  151. return false
  152. }
  153. if (_this.opt.maxHeight && this.height > _this.opt.maxHeight) {
  154. alert('图片高度超出最大限制')
  155. return false
  156. }
  157. if (_this.opt.limitedWidth && this.width != _this.opt.limitedWidth) {
  158. alert('图片宽度不符合要求')
  159. return false
  160. }
  161. if (_this.opt.limitedHeight && this.height != _this.opt.limitedHeight) {
  162. alert('图片高度不符合要求')
  163. return false
  164. }
  165. _this.foreachNum(src, name, this.width, this.height)
  166. }
  167. },
  168. foreachNum: function(src, name, width, height) {
  169. this.createImageBox(src, name, width, height)
  170. if (this.imageList.children.length >= this.opt.num) {
  171. this.removeUploadBox()
  172. }
  173. },
  174. createImageBox: function(src, name, width, height, state = true) {
  175. this.imageBox[this.i] = document.createElement('li')
  176. this.imageBox[this.i].className = 'cupload-image-box'
  177. this.imageBox[this.i].style.position = 'relative'
  178. this.imageBox[this.i].style.display = 'inline-block'
  179. this.imageBox[this.i].style.margin = '0 8px 8px 0'
  180. this.imageBox[this.i].style.backgroundColor = '#fbfdff'
  181. this.imageBox[this.i].style.border = '1px solid #c0ccda'
  182. this.imageBox[this.i].style.borderRadius = '6px'
  183. this.imageBox[this.i].style.WebkitBoxSizing = 'border-box'
  184. this.imageBox[this.i].style.boxSizing = 'border-box'
  185. this.imageBox[this.i].style.width = this.opt.width + 'px'
  186. this.imageBox[this.i].style.height = this.opt.height + 'px'
  187. this.imageList.appendChild(this.imageBox[this.i])
  188. this.createImagePreview(src, width, height)
  189. this.createImageInput(src)
  190. this.createImageDelete(name)
  191. if (!state) {
  192. this.setDefaultImage()
  193. }
  194. var _this = this
  195. for (var m = 0; m <= this.i; m++) {
  196. this.imageBox[m].index = m
  197. this.imageBox[m].onmouseover = function(n) {
  198. return function() {
  199. _this.showImageDelete(n)
  200. }
  201. }(m)
  202. this.imageBox[m].onmouseout = function(n) {
  203. return function() {
  204. _this.hideImageDelete(n)
  205. }
  206. }(m)
  207. }
  208. this.i++
  209. },
  210. createImagePreview: function(src, width, height) {
  211. this.imagePreview[this.i] = document.createElement('img')
  212. this.imagePreview[this.i].className = 'cupload-image-preview'
  213. this.imagePreview[this.i].style.position = 'absolute'
  214. this.imagePreview[this.i].style.top = 0
  215. this.imagePreview[this.i].style.left = 0
  216. this.imagePreview[this.i].style.right = 0
  217. this.imagePreview[this.i].style.bottom = 0
  218. this.imagePreview[this.i].style.margin = 'auto'
  219. this.imagePreview[this.i].src = src
  220. this.setImageAttribute(width, height)
  221. this.imageBox[this.i].appendChild(this.imagePreview[this.i])
  222. },
  223. createImageInput: function(src) {
  224. this.imageInput[this.i] = document.createElement('input')
  225. this.imageInput[this.i].type = 'hidden'
  226. this.imageInput[this.i].name = this.opt.name + '[]'
  227. this.imageInput[this.i].value = src
  228. this.imageBox[this.i].appendChild(this.imageInput[this.i])
  229. },
  230. createImageDelete: function(name) {
  231. this.imageDelete[this.i] = document.createElement('div')
  232. this.imageDelete[this.i].className = 'cupload-image-delete'
  233. this.imageDelete[this.i].style.position = 'absolute'
  234. this.imageDelete[this.i].style.width = '100%'
  235. this.imageDelete[this.i].style.height = '100%'
  236. this.imageDelete[this.i].style.left = 0
  237. this.imageDelete[this.i].style.top = 0
  238. this.imageDelete[this.i].style.textAlign = 'center'
  239. this.imageDelete[this.i].style.color = '#fff'
  240. this.imageDelete[this.i].style.opacity = 0
  241. this.imageDelete[this.i].style.backgroundColor = 'rgba(0,0,0,.5)'
  242. this.imageDelete[this.i].style.WebkitTransition = '.3s'
  243. this.imageDelete[this.i].style.transition = '.3s'
  244. this.imageDelete[this.i].title = name
  245. this.imageBox[this.i].appendChild(this.imageDelete[this.i])
  246. this.createDeleteBtn()
  247. },
  248. createDeleteBtn: function() {
  249. this.deleteBtn[this.i] = document.createElement('span')
  250. this.deleteBtn[this.i].className = 'cupload-delete-btn'
  251. this.deleteBtn[this.i].style.position = 'absolute'
  252. this.deleteBtn[this.i].style.top = 0
  253. this.deleteBtn[this.i].style.right = 0
  254. this.deleteBtn[this.i].style.margin = 0
  255. this.deleteBtn[this.i].style.padding = 0
  256. this.deleteBtn[this.i].style.fontSize = '18px'
  257. this.deleteBtn[this.i].style.width = '24px'
  258. this.deleteBtn[this.i].style.height = '24px'
  259. this.deleteBtn[this.i].style.cursor = 'pointer'
  260. this.deleteBtn[this.i].innerHTML = '×'
  261. this.deleteBtn[this.i].title = ''
  262. this.imageDelete[this.i].appendChild(this.deleteBtn[this.i])
  263. var _this = this
  264. for (var m = 0; m <= this.i; m++) {
  265. this.deleteBtn[m].onclick = function(n) {
  266. return function() {
  267. _this.deleteImage(n)
  268. }
  269. }(m)
  270. }
  271. },
  272. setDefaultImage: function() {
  273. this.imageBox[this.i].style.backgroundColor = "black"
  274. this.imageDelete[this.i].title = '图片不存在'
  275. this.imagePreview[this.i].src = 'data:image/png;base64,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'
  276. if (130 / this.opt.width > 105 / this.opt.height) {
  277. this.imagePreview[this.i].style.width = this.opt.width - 2 + 'px'
  278. this.imagePreview[this.i].style.height = 105 / (130 / this.opt.width) - 2 + 'px'
  279. } else {
  280. this.imagePreview[this.i].style.width = 130 / (105 / this.opt.height) - 2 + 'px'
  281. this.imagePreview[this.i].style.height = this.opt.height - 2 + 'px'
  282. }
  283. },
  284. setImageAttribute: function(width, height) {
  285. if (width / this.opt.width > height / this.opt.height) {
  286. this.imagePreview[this.i].style.width = this.opt.width - 2 + 'px'
  287. this.imagePreview[this.i].style.height = height / (width / this.opt.width) - 2 + 'px'
  288. } else {
  289. this.imagePreview[this.i].style.width = width / (height / this.opt.height) - 2 + 'px'
  290. this.imagePreview[this.i].style.height = this.opt.height - 2 + 'px'
  291. }
  292. },
  293. showImagePreview: function() {
  294. var obj = this.opt.data
  295. if (obj.length >= this.opt.num) {
  296. this.removeUploadBox()
  297. }
  298. var _this = this
  299. var tempImage = new Image()
  300. tempImage.src = obj[this.i]
  301. tempImage.onload = function() {
  302. _this.createImageBox(obj[_this.i], obj[_this.i], this.width, this.height)
  303. setTimeout(function() {
  304. if (obj[_this.i]) {
  305. _this.showImagePreview()
  306. }
  307. }, 0);
  308. }
  309. tempImage.onerror = function() {
  310. _this.createImageBox(obj[_this.i], obj[_this.i], 0, 0, false)
  311. setTimeout(function() {
  312. if (obj[_this.i]) {
  313. _this.showImagePreview()
  314. }
  315. }, 0);
  316. }
  317. },
  318. deleteImage: function(n) {
  319. this.imageBox[n].remove()
  320. this.removeUploadBox()
  321. if (this.imageList.children.length < this.opt.num) {
  322. this.createUploadBox()
  323. }
  324. },
  325. removeUploadBox: function() {
  326. this.uploadBox.remove()
  327. },
  328. showImageDelete: function(m) {
  329. this.imageDelete[m].style.opacity = 1
  330. },
  331. hideImageDelete: function(m) {
  332. this.imageDelete[m].style.opacity = 0
  333. },
  334. }
  335. window.Cupload = Cupload;
  336. })(window, document)