JQuery上传文件(客户端)

  现在工作中使用的文件上传插件是以前的同事使用Flash实现的,最近经常接到客户的反馈说上传插件不能使用,经调查发现是部份客户的浏览器阻止了Flash的运行,需要手动开启Flash才能正常使用,客户体验非常糟糕,毕竟不可能要求每个客户都知道怎么去开启浏览器支持Flash。

  思量过后决定把Flash上传修改为JQuery上传。

  上代码:

  1 ; (function ($, window, document, undefined) {
  2     var fileExtentionAcceptConfig = [
  3         { extention: ".3gpp", accept: "audio/3gpp" },
  4         { extention: ".3gpp", accept: "video/3gpp" },
  5         { extention: ".ac3", accept: "audio/ac3" },
  6         { extention: ".asf", accept: "allpication/vnd.ms-asf" },
  7         { extention: ".au", accept: "audio/basic" },
  8         { extention: ".bmp", accept: "image/bmp" },
  9         { extention: ".css", accept: "text/css" },
 10         { extention: ".csv", accept: "text/csv" },
 11         { extention: ".doc", accept: "application/msword" },
 12         { extention: ".dot", accept: "application/msword" },
 13         { extention: ".dtd", accept: "application/xml-dtd" },
 14         { extention: ".dwg", accept: "image/vnd.dwg" },
 15         { extention: ".dxf", accept: "image/vnd.dxf" },
 16         { extention: ".gif", accept: "image/gif" },
 17         { extention: ".htm", accept: "text/html" },
 18         { extention: ".html", accept: "text/html" },
 19         { extention: ".jp2", accept: "image/jp2" },
 20         { extention: ".jpe", accept: "image/jpeg" },
 21         { extention: ".jpeg", accept: "image/jpeg" },
 22         { extention: ".jpg", accept: "image/jpeg" },
 23         { extention: ".js", accept: "text/javascript" },
 24         { extention: ".js", accept: "application/javascript" },
 25         { extention: ".json", accept: "application/json" },
 26         { extention: ".mp2", accept: "audio/mpeg" },
 27         { extention: ".mp2", accept: "video/mpeg" },
 28         { extention: ".mp3", accept: "audio/mpeg" },
 29         { extention: ".mp4", accept: "audio/mp4" },
 30         { extention: ".mp4", accept: "video/mp4" },
 31         { extention: ".mpeg", accept: "video/mpeg" },
 32         { extention: ".mpg", accept: "video/mpeg" },
 33         { extention: ".mpp", accept: "application/vnd.ms-project" },
 34         { extention: ".ogg", accept: "application/ogg" },
 35         { extention: ".ogg", accept: "audio/ogg" },
 36         { extention: ".pdf", accept: "application/pdf" },
 37         { extention: ".png", accept: "image/png" },
 38         { extention: ".pot", accept: "application/vnd.ms-powerpoint" },
 39         { extention: ".pps", accept: "application/vnd.ms-powerpoint" },
 40         { extention: ".ppt", accept: "application/vnd.ms-powerpoint" },
 41         { extention: ".rtf", accept: "application/rtf" },
 42         { extention: ".rtf", accept: "text/rtf" },
 43         { extention: ".svf", accept: "image/vnd.svf" },
 44         { extention: ".tif", accept: "image/tiff" },
 45         { extention: ".tiff", accept: "image/tiff" },
 46         { extention: ".txt", accept: "text/plain" },
 47         { extention: ".wdb", accept: "application/vnd.ms-works" },
 48         { extention: ".wps", accept: "application/vnd.ms-works" },
 49         { extention: ".xhtml", accept: "application/xhtml+xml" },
 50         { extention: ".xlc", accept: "application/vnd.ms-excel" },
 51         { extention: ".xlm", accept: "application/vnd.ms-excel" },
 52         { extention: ".xls", accept: "application/vnd.ms-excel" },
 53         { extention: ".xlt", accept: "application/vnd.ms-excel" },
 54         { extention: ".xlw", accept: "application/vnd.ms-excel" },
 55         { extention: ".xml", accept: "text/xml" },
 56         { extention: ".xml", accept: "application/xml" },
 57         { extention: ".zip", accept: "aplication/zip" },
 58         { extention: ".xlsx", accept: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" }
 59     ];
 60 
 61     var fileTypeConfig = [
 62         { id: 1, name: "商品图片", code: "product" },
 63         { id: 2, name: "PC端装修图片", code: "template" },
 64         { id: 3, name: "其它图片", code: "other" },
 65         { id: 4, name: "手机端装修图片", code: "H5Decorating" },
 66         { id: 5, name: "手机端装修图片", code: "APPDecorating" },
 67         { id: 6, name: "订单相关图片(退货、换货)", code: "Order" },
 68         { id: 7, name: "会员营业执照", code: "UserBusinessLicense" },
 69         { id: 8, name: "会员身份证", code: "UserIDCard" },
 70         { id: 9, name: "试装会员", code: "TrailUser" },
 71         { id: 10, name: "建议反馈", code: "Suggest" },
 72         { id: 11, name: "会员", code: "User" },
 73         { id: 12, name: "设置", code: "Site" },
 74         { id: 13, name: "Childmap", code: "Childmap" }
 75     ];
 76 
 77     var jqueryUpload = function (ele, opt) {
 78         var $this = this;
 79 
 80         $this.$element = $(ele);
 81         $this._default = {
 82             uploadUrl: "/controls/Upload.ashx",
 83             buttonStyle: {
 84                 "display": "inline-block",
 85                 "background-color": "#EC7B65",
 86                 "color": "white",
 87                 "padding": "4px 10px",
 88                 "border-radius": "2px",
 89                 "cursor": "pointer",
 90                 "font-size": "12px",
 91                 "line-height": "18px"
 92             },
 93             offerId: null,//客户ID
 94             uploadFolderId: null,//文件夹ID
 95             uploadFolderName: null,//文件夹名称,上传路径='uploads/类型code/uploadName'
 96             fileType: null,//文件类型1|2|3...
 97             noThumb: true,//不生成缩略图
 98             waterMark: null,//是否生成水印
 99             fileCount: 1,
100             maxSize: 1024,//图片最大尺寸,单位KB;默认1M=1024*1024
101             allowFileType: null,//支持的文件类型,可为后缀名数组:['.jpg', '.png'...],也可以是字符串表式一类文件:'image'|'audio'...
102             multiple: false,
103             onError: null,
104             onSelected: null,
105             onProcess: null,
106             onUploaded: null
107         };
108         $this.option = $.extend({}, true, $this._default, opt);
109         if ($$.isString($this.option.allowFileType)) {
110             $this.option.allowFileType = $$.sae(fileExtentionAcceptConfig)
111                 .findAll(function (x) { return $$.soe(x.accept).startWith($this.option.allowFileType); })
112                 .select(function (x) { return x.extention; })
113                 .toArray();
114         }
115 
116         $this.controlId = $this.generateId();
117         $this.initControl();
118     }
119 
120     jqueryUpload.prototype = {
121         resetOption: function (option) {
122             var $this = this;
123 
124             $this.option = $.extend($this.option, option);
125             $this.initControl();
126         },
127         initControl: function () {
128             var $this = this;
129 
130             var html = "\
131 <div id='ju-" + $this.controlId + "' class='ju-container'>";
132             $this.$filecontrolHtml = "\
133     <input type='file'";
134             if ($$.isArray($this.option.allowFileType)) {
135                 var accepts = $$.sae(fileExtentionAcceptConfig)
136                     .findAll(function (x) { return $$.sae($this.option.allowFileType).any(function (y) { return $$.compare(x.extention, y, true) == 0 }); })
137                     .select(function (x) { return x.accept; })
138                     .distinct()
139                     .toArray();
140                 $this.$filecontrolHtml += " accept='" + accepts.join(',') + "'";
141             }
142             if ($this.option.multiple) {
143                 $this.$filecontrolHtml += " multiple='multiple'";
144             }
145             $this.$filecontrolHtml += " style='display:none;' />";
146             html += "\
147     <span class='ju-upload'>上传</span>\
148 </div>";
149             $this.$element.html(html);
150 
151             $this.$container = $this.$element.find(".ju-container");
152             $this.resetInputControl();
153             $this.$uploadbutton = $this.$container.find(".ju-upload");
154             if ($$.isObject($this.option.buttonStyle)) {
155                 $this.$uploadbutton.css($this.option.buttonStyle);
156                 $this.$uploadbutton.hover(function () {
157                     $this.$uploadbutton.css({
158                         "background-color": "#EF8E7C"
159                     });
160                 }, function () {
161                     $this.$uploadbutton.css({
162                         "background-color": "#EC7B65"
163                     });
164                 });
165             } else {
166                 $this.$uploadbutton.addClass($this.option.buttonStyle);
167             }
168 
169             $this.$uploadbutton.click(function () {
170                 $this.$filecontrol.click();
171             });
172         },
173         resetInputControl: function () {
174             var $this = this;
175 
176             if (!$$.isNullOrUndefined($this.$filecontrol)) {
177                 $this.$filecontrol.remove();
178             }
179 
180             $this.$container.append($this.$filecontrolHtml);
181             $this.$filecontrol = $this.$container.find("input[type='file']");
182             $this.$filecontrol.change(function () {
183                 $this.fileSelected();
184             });
185         },
186         fileSelected: function () {
187             var $this = this;
188 
189             var aeFile = $$.ae($this.$filecontrol[0].files);
190 
191             if (aeFile.any(function (x) {
192                 var fileExtention = $$.getFileExtention(x.name);
193                 return !$$.sae($this.option.allowFileType).any(function (y) { return $$.compare(y, fileExtention, true) == 0; });
194             })) {
195                 $this.error("不支持的文件类型!");
196                 return;
197             }
198 
199             if (aeFile.any(function (x) { return x.size > $this.option.maxSize * 1024; })) {
200                 $this.error("文件大小不得超过" + ($this.option.maxSize >= 1024 ? $$.soe($this.option.maxSize / 1024).round(2, $$.enumeration.roundType.floor) + "MB" : $this.option.maxSize + "KB"));
201                 return;
202             }
203 
204             $.xtcShowLoading("上传中。。。");
205             $.when(aeFile.forEachAsync(function (x) {
206                 if ($$.isFunction($this.option.onSelected)) {
207                     var reader = new FileReader();
208                     reader.onload = function (e) {
209                         var $img = $("<img />");
210                         //$img.attr("src", e.target.result);
211                         //$img.attr("data-url", window.URL.createObjectURL(file));
212                         var imageUrl = window.URL.createObjectURL(x);
213                         $img.attr("src", imageUrl).css("cursor", "pointer");
214                         $this.option.onSelected($img);
215                         $img.click(function () {
216                             window.open(imageUrl);
217                         });
218                     }
219                     reader.readAsDataURL(x);
220                 }
221 
222                 return $this.upload(x);
223             }, $)).done(function (data) {
224                 data = $$.sae(data)
225                     .findAll(function (x) { return !$$.isNullOrWhiteSpace(x); })
226                     .toArray();
227                 if (data.length == 0) {
228                     return;
229                 } else if (data.length == 1) {
230                     $this.option.onUploaded(data[0])
231                 } else {
232                     $this.option.onUploaded(data);
233                 }
234                 
235                 $this.resetInputControl();
236             }).always(function () {
237                 $.xtcHideLoading();
238             });
239         },
240         error: function (msg) {
241             var $this = this;
242 
243             if ($$.isFunction($this.option.onError)) {
244                 $this.option.onError(msg);
245             }
246 
247             $this.resetInputControl();
248         },
249         process: function (evt) {
250             var $this = this;
251             
252             if ($$.isFunction($this.option.onProcess)) {
253                 $this.option.onProcess(evt.total, evt.loaded);
254             }
255         },
256         upload: function (file) {
257             var defer = $.Deferred();
258 
259             var $this = this;
260 
261             var formData = new FormData();
262             formData.append("file", file);
263             
264             try {
265                 var params = [];
266                 if (!$$.isNullOrUndefined($this.option.offerId)) {
267                     params.push("offerid=" + $this.option.offerId);
268                     if ($$.soe($this.option.offerId).toInt() > 0) {
269                         params.push("isoffer=1");
270                     }
271                 }
272                 if (!$$.isNullOrUndefined($this.option.uploadFolderId)) {
273                     params.push("cid=" + $this.option.uploadFolderId);
274                 }
275                 var uploadDir = "uploads";
276                 var fileType = null;
277                 if (!$$.isNullOrUndefined($this.option.fileType)) {
278                     var fileTypeId = $$.soe($this.option.fileType).toInt();
279                     params.push("type=" + fileTypeId);
280                     var fileType = $$.sae(fileTypeConfig)
281                         .firstOrDefault(function (x) { return x.id == fileTypeId; });
282                 }
283                 if (fileType != null) {
284                     uploadDir += "/" + fileType.code;
285                 } else {
286                     uploadDir += "/unknown";
287                 }
288                 if (!$$.isNullOrWhiteSpace($this.option.uploadFolderName)) {
289                     uploadDir += "/" + $this.option.uploadFolderName;
290                 }
291                 params.push("upload_dir=" + uploadDir);
292                 if (!$$.isNullOrUndefined($this.option.noThumb)) {
293                     params.push("no_thumb=" + ($this.option.noThumb ? 1 : 0));
294                 }
295                 if (!$$.isNullOrUndefined($this.option.waterMark)) {
296                     params.push("WaterMark=" + ($this.option.waterMark ? 1 : 0));
297                 }
298                 $.ajax({
299                     url: $this.option.uploadUrl + "?" + params.join('&'),
300                     type: "POST",
301                     data: formData,
302                     async: true,
303                     contentType: false,
304                     processData: false,
305                     dataType: "html",
306                     xhr: function () {
307                         var xhr = $.ajaxSettings.xhr();
308                         xhr.upload.addEventListener("progress", function (evt) { $this.process(evt); }, false);
309                         return xhr;
310                     }
311                 }).done(function (data) {
312                     if ($$.isNullOrUndefined(data)) {
313                         $this.error("上传失败,未知错误!");
314                         defer.resolve("");
315                     } else if (data.indexOf(".") <= 0) {
316                         $this.error(data);
317                         defer.resolve("");
318                     } else if ($$.isFunction($this.option.onUploaded)) {
319                         defer.resolve(data);
320                     }
321                 }).fail(function (err) {
322                     if (typeof (err) == "object" && err.constructor == Object && err.responseText) {
323                         $this.error(err.responseText);
324                     } else {
325                         $this.error(err);
326                     }
327                     defer.resolve("");
328                 });
329             }
330             catch (err) {
331                 if (typeof (err) == "object" && err.constructor == Object && err.responseText) {
332                     $this.error(err.responseText);
333                 } else {
334                     $this.error(err);
335                 }
336                 defer.resolve("");
337             }
338 
339             return defer;
340         },
341         generateId: function () {
342             var guid = "";
343             for (var i = 1; i <= 32; i++) {
344                 var n = Math.floor(Math.random() * 16.0).toString(16);
345                 guid += n;
346                 if ((i == 8) || (i == 12) || (i == 16) || (i == 20))
347                     guid += "-";
348             }
349             return guid;
350         }
351     }
352 
353     $.fn.xtcUpload = function (option) {
354         return new jqueryUpload(this, option);
355     }
356 })(jQuery, window, document);
View Code

  如何使用?

<script type="text/javascript" src="http://jsl.solomon-yu.cn/JSE/jsExtension.min.js"></script><!--使用了上一篇随笔里编写的JS扩展插件,需要引入-->
<script type="text/javascript" src="/common_script/jqueryUpload.js"></script>
<script type="text/javascript">
    $(function () {
        var uploadControl = $(".uploadTest").xtcUpload({
            buttonStyle: "upload-button",//按钮样式,可以是一个css键值对实体,也可以是一个class名称
            uploadFolderId: 220,//上传文件夹ID
            uploadFolderName: '10月20日活动页',//上传文件夹名称
            fileType: 3,//文件类型,对应于JS文件中的fileTypeConfig
            maxSize: 500,//文件大小限制单位KB
            allowFileType: [".png", ".jpg"],//支持的文件类型,可为后缀名数组:['.jpg', '.png'...],也可以是字符串表式一类文件:'image'|'audio'...
            //发生错误时调用的函数
            onError: function (msg) {
                Ecshop.Tool.Hint.Error({ info: msg });
            },
            //上传时进度条触发事件
            onProcess: function (total, loaded) {
                //百分比 loaded / total * 100
            },
            //上传完成时触发事件
            onUploaded: function (file) {
                $(".img-before-upload").append("<img src='/" + file + "' />");
            }
        });
        //当需要时(如上传文件夹变更)重置上传控件参数
        uploadControl.resetOption({
            uploadFolderId: 221
        });
    });
</script>
<div class="uploadTest"></div>
<div class="img-before-upload"></div>

posted on 2017-10-09 17:59  众从人  阅读(1041)  评论(0编辑  收藏  举报

导航