jquery文件上传控件 WebUploader

2019年11月29日 阅读数:119
这篇文章主要向大家介绍jquery文件上传控件 WebUploader,主要内容包括基础应用、实用技巧、原理机制等方面,希望对大家有所帮助。

WebUploader是百度开源的一个文件上传组件,由于其操做简洁大方,就在项目中使用了,记录一下。 javascript

效果是这样子: 
这里写图片描述 
这个样子是默认的效果。php

这里写图片描述 
这个是选择上传的图片,能够批量,选择后能够删除和添加更多。css

这里写图片描述 
这个是上传过程显示的效果。html


  
  
  1. < div id = "container" >
  2. <! --头部,相册选择和格式选择-->
  3. < div id = "uploader" >
  4. < div class = "queueList" >
  5. < div id = "dndArea" class = "placeholder" >
  6. < div id = "filePicker" > </ div >
  7. <p> <s: text name = "resource.upload.tip" /> </p>
  8. </ div >
  9. </ div >
  10. < div class = "statusBar" style= "display:none;" >
  11. < div class = "progress" >
  12. <span class = "text" > 0% </span>
  13. <span class = "percentage" > </span>
  14. </ div >
  15. < div class = "info" > </ div >
  16. < div class = "btns" >
  17. < div id = "filePicker2" > </ div >
  18. < div class = "uploadBtn" > <s: text name = "resource.starttoupload" > </s: text > </ div >
  19. </ div >
  20. </ div >
  21. </ div >
  22. </ div >
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

js部分代码,下面这段代码是webuploader官方的示例代码uploader.js作的修改:java


  
  
  1. (function( $ ){
  2. // 当domReady的时候开始初始化
  3. $ (function() {
  4. var filePerSize = [];//每一个文件大小
  5. var fileName = [];
  6. var fileSize = 0;
  7. var $wrap = $('#uploader'),
  8. // 图片容器
  9. $queue = $('<ul class="filelist"></ul>').appendTo($wrap.find('.queueList')),
  10. // 状态栏,包括进度和控制按钮
  11. $statusBar = $wrap.find('.statusBar'),
  12. // 文件整体选择信息。
  13. $info = $statusBar.find('.info'),
  14. // 上传按钮
  15. $upload = $wrap.find('.uploadBtn'),
  16. // 没选择文件以前的内容。
  17. $placeHolder = $wrap.find('.placeholder'),
  18. $progress = $statusBar.find('.progress').hide(),
  19. // 添加的文件数量
  20. fileCount = 0,
  21. // 添加的文件总大小
  22. fileSize = 0,
  23. // 优化retina, 在retina下这个值是2
  24. ratio = window.devicePixelRatio || 1,
  25. // 缩略图大小
  26. thumbnailWidth = 110 * ratio,
  27. thumbnailHeight = 110 * ratio,
  28. // 可能有pedding, ready, uploading, confirm, done.
  29. state = 'pedding',
  30. // 全部文件的进度信息,key为file id
  31. percentages = {},
  32. // 判断浏览器是否支持图片的base64
  33. isSupportBase64 = ( function() {
  34. var data = new Image();
  35. var support = true;
  36. data.onload = data.onerror = function() {
  37. if( this.width != 1 || this.height != 1 ) {
  38. support = false;
  39. }
  40. }
  41. data.src = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==";
  42. return support;
  43. }) (),
  44. // 检测是否已经安装flash,检测flash的版本
  45. flashVersion = ( function() {
  46. var version;
  47. try {
  48. version = navigator.plugins[ 'Shockwave Flash' ];
  49. version = version.description;
  50. } catch ( ex ) {
  51. try {
  52. version = new ActiveXObject('ShockwaveFlash.ShockwaveFlash')
  53. .GetVariable('$version');
  54. } catch ( ex2 ) {
  55. version = '0.0';
  56. }
  57. }
  58. version = version.match( /\d+/g );
  59. return parseFloat( version[ 0 ] + '.' + version[ 1 ], 10 );
  60. } ) (),
  61. supportTransition = (function(){
  62. var s = document.createElement('p').style,
  63. r = 'transition' in s ||
  64. 'WebkitTransition' in s ||
  65. 'MozTransition' in s ||
  66. 'msTransition' in s ||
  67. 'OTransition' in s;
  68. s = null;
  69. return r;
  70. }) (),
  71. // WebUploader实例
  72. uploader;
  73. if ( !WebUploader.Uploader.support('flash') && WebUploader.browser.ie ) {
  74. // flash 安装了可是版本太低。
  75. if (flashVersion) {
  76. (function(container) {
  77. window['expressinstallcallback'] = function( state ) {
  78. switch(state) {
  79. case 'Download.Cancelled':
  80. //alert('您取消了更新!')
  81. break;
  82. case 'Download.Failed':
  83. //alert('安装失败')
  84. break;
  85. default:
  86. //alert('安装已成功,请刷新!');
  87. break;
  88. }
  89. delete window['expressinstallcallback'];
  90. } ;
  91. var swf = './expressInstall.swf';
  92. // insert flash object
  93. var html = '<object type="application/' +
  94. 'x-shockwave-flash" data= "' + swf + '" ' ;
  95. if (WebUploader.browser.ie) {
  96. html += 'classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" ';
  97. }
  98. html += 'width="100%" height="100%" style="outline:0">' +
  99. '<param name="movie" value="' + swf + '" />' +
  100. '<param name="wmode" value="transparent" />' +
  101. '<param name="allowscriptaccess" value="always" />' +
  102. '</object>';
  103. container.html(html);
  104. }) ($wrap) ;
  105. // 压根就没有安转。
  106. } else {
  107. $wrap.html('<a href="http://www.adobe.com/go/getflashplayer" target="_blank" border="0"><img alt="get flash player" src="http://www.adobe.com/macromedia/style_guide/images/160x41_Get_Flash_Player.jpg" /></a>');
  108. }
  109. return;
  110. } else if (!WebUploader.Uploader.support()) {
  111. alert( 'Web Uploader not support your browser!');
  112. return;
  113. }
  114. // 实例化
  115. uploader = WebUploader.create({
  116. pick: {
  117. id: '#filePicker',
  118. name: 'multiFile',
  119. label: 'Click To Select'
  120. },
  121. formData: {
  122. "status": "multi",
  123. "contentsDto.contentsId": "xxxx",
  124. "uploadNum": "xxxx",
  125. "existFlg": "false",
  126. },
  127. dnd: '#dndArea',
  128. paste: '#uploader',
  129. method: 'POST',
  130. swf: '../../dist/Uploader.swf',
  131. chunked: false,
  132. chunkSize: 512 * 1024,
  133. chunkRetry:false,
  134. server: 'resource/upload.action?resourcetype=hd',
  135. fileVal:'multiFile',
  136. resize: false,
  137. // runtimeOrder: 'flash',
  138. /* accept: {
  139. title: 'Images',
  140. extensions: 'gif,jpg,bmp,png,m2v',
  141. mimeTypes: 'image/*,video/mpeg',
  142. } , */
  143. // 禁掉全局的拖拽功能。这样不会出现图片拖进页面的时候,把图片打开。
  144. disableGlobalDnd: true,
  145. fileNumLimit: 300,
  146. fileSizeLimit: 200 * 1024 * 1024, // 200 M
  147. fileSingleSizeLimit: 50 * 1024 * 1024 // 50 M
  148. }) ;
  149. // 拖拽时不接受 js, txt 文件。
  150. uploader.on('dndAccept', function( items ) {
  151. var denied = false,
  152. len = items.length,
  153. i = 0,
  154. // 修改js类型
  155. unAllowed = 'text/plain;application/javascript ';
  156. for ( ; i < len; i++ ) {
  157. // 若是在列表里面
  158. if ( ~unAllowed.indexOf( items[ i ].type ) ) {
  159. denied = true;
  160. break;
  161. }
  162. }
  163. return !denied;
  164. }) ;
  165. //点击按钮弹出选择框
  166. /*uploader.on('dialogOpen', function() {
  167. console.log ('here') ;
  168. } ) ;*/
  169. // 添加"添加文件"的按钮,
  170. uploader.addButton({
  171. id: '#filePicker2',
  172. label: '<s:text name="resource.addmore"></s:text>'
  173. }) ;
  174. uploader.on('ready', function() {
  175. window.uploader = uploader;
  176. }) ;
  177. // 当有文件添加进来时执行,负责view的建立
  178. function addFile( file ) {
  179. var $li = $( '<li id="' + file.id + '">' +
  180. '<p class="title">' + file.name + '</p>' +
  181. '<p class="imgWrap"></p>'+
  182. '<p class="progress"><span></span></p>' +
  183. '</li>' ),
  184. $btns = $('<div class="file-panel">' +
  185. '<span class="cancel"><s:text name="resource.delete"></s:text></span>' +
  186. '<span class="rotateRight"><s:text name="resource.rotateToRight"></s:text></span>' +
  187. '<span class="rotateLeft"><s:text name="resource.rotateToLeft"></s:text></span></div>').appendTo ( $li ),
  188. $prgress = $li.find('p.progress span'),
  189. $wrap = $li.find( 'p.imgWrap' ),
  190. $info = $('<p class="error"></p>'),
  191. showError = function( code ) {
  192. switch( code ) {
  193. case 'exceed_size':
  194. text = '<s:text name="resource.exceedSize"></s:text>';
  195. break;
  196. case 'interrupt':
  197. text = '<s:text name="resource.pauseupload"></s:text>';
  198. break;
  199. default:
  200. text = '<s:text name="resource.uploadfailed"></s:text>';
  201. break;
  202. }
  203. $info.text( text ).appendTo( $li );
  204. } ;
  205. if ( file.getStatus() === 'invalid' ) {
  206. showError( file.statusText );
  207. } else {
  208. // @todo lazyload
  209. $wrap.text( '<s:text name="resource.onPreview"></s:text>' );
  210. uploader.makeThumb( file, function( error, src ) {
  211. var img;
  212. if ( error ) {
  213. $wrap.text( '<s:text name="resource.unablePreview"></s:text>' );
  214. return;
  215. }
  216. if( isSupportBase64 ) {
  217. img = $('<img src="'+src+'">');
  218. $wrap.empty().append( img );
  219. } else {
  220. /*$.ajax('../../server/preview.php', {
  221. method: 'POST',
  222. data: src,
  223. dataType :'json'
  224. } ) .done (function( response ) {
  225. if (response.result) {
  226. img = $ ('<img src="'+response.result+'">') ;
  227. $wrap.empty () .append ( img ) ;
  228. } else {
  229. $wrap.text ("预览出错") ;
  230. }
  231. } ) ;*/
  232. }
  233. }, thumbnailWidth, thumbnailHeight ) ;
  234. percentages[ file.id ] = [ file.size, 0 ];
  235. file.rotation = 0;
  236. }
  237. file.on('statuschange', function( cur, prev ) {
  238. if ( prev === 'progress' ) {
  239. $prgress.hide().width(0);
  240. } else if ( prev === 'queued' ) {
  241. $li.off( 'mouseenter mouseleave' );
  242. $btns.remove();
  243. }
  244. // 成功
  245. if (cur === 'error' || cur === 'invalid') {
  246. console.log( file.statusText );
  247. showError( file.statusText );
  248. percentages[ file.id ][ 1 ] = 1;
  249. } else if ( cur === 'interrupt' ) {
  250. showError( 'interrupt' );
  251. } else if ( cur === 'queued' ) {
  252. $info.remove();
  253. $prgress.css('display', 'block');
  254. percentages[ file.id ][ 1 ] = 0;
  255. } else if ( cur === 'progress' ) {
  256. $info.remove();
  257. $prgress.css('display', 'block');
  258. } else if ( cur === 'complete' ) {
  259. $prgress.hide().width(0);
  260. $li.append('<span class="success"></span>');
  261. }
  262. $li.removeClass('state-' + prev).addClass('state-' + cur);
  263. }) ;
  264. $li.on('mouseenter', function() {
  265. $btns.stop().animate({height: 30});
  266. }) ;
  267. $li.on('mouseleave', function() {
  268. $btns.stop().animate({height: 0});
  269. }) ;
  270. $btns.on('click', 'span', function() {
  271. var index = $(this).index(),
  272. deg;
  273. switch (index) {
  274. case 0:
  275. uploader.removeFile( file );
  276. return;
  277. case 1:
  278. file.rotation += 90;
  279. break;
  280. case 2:
  281. file.rotation -= 90;
  282. break;
  283. }
  284. if (supportTransition) {
  285. deg = 'rotate(' + file.rotation + 'deg)';
  286. $wrap.css({
  287. '-webkit-transform': deg,
  288. '-mos-transform': deg,
  289. '-o-transform': deg,
  290. 'transform': deg
  291. }) ;
  292. } else {
  293. $wrap.css( 'filter', 'progid:DXImageTransform.Microsoft.BasicImage(rotation='+ (~~((file.rotation/90)%4 + 4)%4) +')');
  294. }
  295. }) ;
  296. $li.appendTo($queue);
  297. }
  298. // 负责view的销毁
  299. function removeFile( file ) {
  300. var $li = $('#'+file.id);
  301. delete percentages[ file.id ];
  302. updateTotalProgress();
  303. $li.off().find('.file-panel').off().end().remove();
  304. }
  305. function updateTotalProgress() {
  306. var loaded = 0,
  307. total = 0,
  308. spans = $progress.children(),
  309. percent;
  310. $.each( percentages, function( k, v ) {
  311. total += v[ 0 ];
  312. loaded += v[ 0 ] * v[ 1 ];
  313. } ) ;
  314. percent = total ? loaded / total : 0;
  315. spans.eq( 0 ).text(Math.round( percent * 100 ) + '%');
  316. spans.eq( 1 ).css('width', Math.round( percent * 100 ) + '%');
  317. updateStatus();
  318. }
  319. function updateStatus() {
  320. var text = '', stats;
  321. if ( state === 'ready' ) {
  322. text = '<s:text name="resource.selected"></s:text>' + fileCount + ', <s:text name="resource.totalSize"></s:text>' +
  323. WebUploader.formatSize(fileSize);
  324. } else if ( state === 'confirm' ) {
  325. stats = uploader.getStats();
  326. if ( stats.uploadFailNum ) {
  327. text = '<s:text name="resource.uploaded"></s:text>' + stats.successNum+ ', <s:text name="resource.failed"></s:text>'+
  328. stats.uploadFailNum + ', <a class="retry" href="#" style="color:red;">' + '<s:text name="resource.retry"></s:text>'+'</a>&nbsp;<s:text name="resource.or"></s:text><a class="ignore" href="#" style="color:blue;">&nbsp;<s:text name="resource.ignore"></s:text></a>'
  329. }
  330. } else {
  331. stats = uploader.getStats();
  332. text = '<s:text name="resource.total"></s:text>' + fileCount + '(' +
  333. WebUploader.formatSize( fileSize ) +
  334. ') , <s :text name= "resource.uploaded" ></s :text> :' + stats.successNum ;
  335. if ( stats.uploadFailNum ) {
  336. text += ', <s:text name="resource.failed"></s:text>:' + stats.uploadFailNum;
  337. }
  338. }
  339. $info.html(text);
  340. }
  341. /*关闭上传框窗口后恢复上传框初始状态*/
  342. function closeUploader() {
  343. // 移除全部缩略图并将上传文件移出上传序列
  344. for (var i = 0; i < uploader.getFiles().length; i++) {
  345. // 将图片从上传序列移除
  346. uploader.removeFile(uploader.getFiles()[i]);
  347. // 将图片从缩略图容器移除
  348. var $li = $('#' + uploader.getFiles()[i].id);
  349. $li.off().remove();
  350. }
  351. setState('pedding');
  352. // 重置文件总个数和总大小
  353. fileCount = 0;
  354. fileSize = 0;
  355. // 重置uploader,目前只重置了文件队列
  356. uploader.reset();
  357. // 更新状态等,从新计算文件总个数和总大小
  358. updateStatus();
  359. }
  360. function setState( val ) {
  361. var file, stats;
  362. if ( val === state ) {
  363. return;
  364. }
  365. $upload.removeClass( 'state-' + state );
  366. $upload.addClass( 'state-' + val );
  367. state = val;
  368. switch (state) {
  369. case 'pedding':
  370. $placeHolder.removeClass( 'element-invisible' );
  371. $queue.hide();
  372. $statusBar.addClass( 'element-invisible' );
  373. uploader.refresh();
  374. break;
  375. case 'ready':
  376. $placeHolder.addClass( 'element-invisible' );
  377. $( '#filePicker2' ).removeClass( 'element-invisible');
  378. $queue.show();
  379. $statusBar.removeClass('element-invisible');
  380. uploader.refresh();
  381. break;
  382. case 'uploading':
  383. $( '#filePicker2' ).addClass( 'element-invisible' );
  384. $progress.show();
  385. $upload.text( '<s:text name="resource.pauseupload"></s:text>' );
  386. var fileArray1 = uploader.getFiles();
  387. var fileNames = [];
  388. fileSize = 0;
  389. for(var i=0; i<fileArray1.length; i++) {
  390. fileNames.push(fileArray1[i].name);
  391. fileSize += fileArray1[i].size;
  392. filePerSize.push(fileArray1[i].size);
  393. fileName.push(fileArray1[i].name);
  394. }
  395. $.extend(true, uploader.options.formData, {"fileSize": fileSize, "multiFileName": fileName, "filePerSize": filePerSize});
  396. break;
  397. case 'paused':
  398. $progress.show();
  399. $upload.text('<s:text name="resource.continueupload"></s:text>');
  400. break;
  401. case 'confirm':
  402. $progress.hide();
  403. $('#filePicker2').removeClass('element-invisible');
  404. $upload.text('<s:text name="resource.starttoupload"></s:text>');
  405. stats = uploader.getStats();
  406. if (stats.successNum && !stats.uploadFailNum) {
  407. setState('finish');
  408. return;
  409. }
  410. break;
  411. case 'finish':
  412. stats = uploader.getStats();
  413. //alert(stats.successNum);
  414. if (stats.successNum) {
  415. if(flag) {
  416. //alert('上传成功');
  417. confirmBox("<s:text name='resource.tiptitle'></s:text>",
  418. "Upload Success",
  419. function(tag) {
  420. if (tag) {
  421. var url = 'resource/uploadHd.jsp';
  422. loadUrl(url);
  423. } else {
  424. return;
  425. }
  426. }) ;
  427. $("#boxwhite a[name=f]").html("<s:text name="box.no"/>").hide();
  428. $("#boxwhite a[name=t]").html("<s:text name="box.sure"/>");
  429. } else {
  430. loadUrl('resource/uploadHd.jsp');
  431. }
  432. //刷新界面
  433. //setTimeout("loadUrl('resource/uploadHd.jsp')", 1000);
  434. } else {
  435. // 没有成功的图片,重设
  436. state = 'done';
  437. location.reload();
  438. }
  439. break;
  440. }
  441. updateStatus();
  442. }
  443. var flag = true;
  444. uploader.on("uploadAccept", function(object, ret){
  445. if(ret != null && ret != '') {
  446. var data = JSON.parse(ret._raw);
  447. if(data != null && data != '') {
  448. if(data.resultCode == '1' || data.resultCode == '2') {
  449. var tip = '';
  450. if(data.resultCode == '1') {
  451. tip = "<s:text name='resource.fileExists'></s:text>";
  452. } else {
  453. tip = "<s:text name='resource.fileTypeError'></s:text>" + data.message;
  454. }
  455. confirmBox("<s:text name='resource.tiptitle'></s:text>",
  456. tip,