基于 zepto,支持多文件上传,进度和图片预览,用于手机端。
- (function($) {
- $.extend($, {
- fileUpload: function(options) {
- var para = {
- multiple: true,
- filebutton: ".filePicker",
- uploadButton: null,
- url: "/home/MUploadImg",
- filebase: "mfile",
- //mvc后台需要对应的名称
- auto: true,
- previewZoom: null,
- uploadComplete: function(res) {
- console.log("uploadComplete", res);
- },
- uploadError: function(err) {
- console.log("uploadError", err);
- },
- onProgress: function(percent) { // 提供给外部获取单个文件的上传进度,供外部实现上传进度效果
- console.log(percent);
- },
- };
- para = $.extend(para, options);
- var $self = $(para.filebutton);
- //先加入一个file元素
- var multiple = ""; // 设置多选的参数
- para.multiple ? multiple = "multiple": multiple = "";
- $self.CSS('position', 'relative');
- $self.append('<input id="fileImage" style="opacity:0;position:absolute;top: 0;left: 0;width:100%;height:100%" type="file" size="30" name="fileselect[]" ' + multiple + '>');
- var doms = {
- "fileToUpload": $self.parent().find("#fileImage"),
- // "thumb": $self.find(".thumb"),
- // "progress": $self.find(".upload-progress")
- };
- var core = {
- fileSelected: function() {
- var files = (doms.fileToUpload)[0].files;
- var count = files.length;
- console.log("共有" + count + "个文件");
- for (var i = 0; i < count; i++) {
- var item = files[i];
- console.log(item.size);
- if (para.auto) {
- core.uploadFile(item);
- }
- core.previewImage(item);
- }
- },
- uploadFile: function(file) {
- console.log("开始上传");
- var formdata = new FormData();
- formdata.append(para.filebase, file); //这个名字要和mvc后台配合
- var xhr = new XMLHttpRequest();
- xhr.upload.addEventListener("progress",
- function(e) {
- var percentComplete = Math.round(e.loaded * 100 / e.total);
- para.onProgress(percentComplete.toString() + '%');
- });
- xhr.addEventListener("load",
- function(e) {
- para.uploadComplete(xhr.responseText);
- });
- xhr.addEventListener("error",
- function(e) {
- para.uploadError(e);
- });
- xhr.open("post", para.url, true);
- //xhr.setRequestHeader("X_FILENAME", file.name);
- xhr.send(formdata);
- },
- uploadFiles: function() {
- var files = (doms.fileToUpload)[0].files;
- for (var i = 0; i < files.length; i++) {
- core.uploadFile(files[i]);
- }
- },
- previewImage: function(file) {
- if (!para.previewZoom) return;
- var img = document.createElement("img");
- img.file = file;
- $(para.previewZoom).append(img);
- // 使用FileReader方法显示图片内容
- var reader = new FileReader();
- reader.onload = (function(aImg) {
- return function(e) {
- aImg.src = e.target.result;
- };
- })(img);
- reader.readAsDataURL(file);
- }
- }
- doms.fileToUpload.on("change",
- function() {
- //doms.progress.find("span").width("0");
- console.log("选中了文件");
- core.fileSelected();
- });
- console.log("初始化!");
- //绑定事件
- $(document).on("click", para.filebutton,
- function() {
- console.log("clicked");
- //doms.fileToUpload.click();
- });
- if (para.uploadButton) {
- $(document).on("click", para.uploadButton,
- function() {
- core.uploadFiles();
- });
- }
- }
- });
- })(Zepto);
简单讲解:上传还是得靠 file 元素,所以一开始就加了个隐藏的, 简单隐藏会有一些问题,有时候不能触发 file change 事件。所以用了透明度, 将父类设置为相对位置。然后通过 file 的 change 事件获得需要上传的文件并放入 formdata 中,再使用 xmlHttpRequest 发请求。进度条是直接绑定的 process 事件。文件预览是 filereader,另外需要注意的就是 filebase 参数,对应的是 MVC 后台上传方法的参数的名称,如果不一致,后台将获取不到 file。回调函数就不说了。
- [HttpPost]
- public ActionResult MUploadImg(HttpPostedFileBase mfile)
- {
- return UploadImg(mfile, "Mobile");
- }
- [HttpPost] public ActionResult UploadImg(HttpPostedFileBase file, string dir = "UserImg") {
- if (CheckImg(file, imgtypes) != "ok") return Json(new {
- Success = false,
- Message = "文件格式不对!"
- },
- JsonRequestBehavior.AllowGet);
- if (file != null) {
- var path = "~/Content/UploadFiles/" + dir + "/";
- var uploadpath = Server.MapPath(path);
- if (!Directory.Exists(uploadpath)) {
- Directory.CreateDirectory(uploadpath);
- }
- string fileName = Path.GetFileName(file.FileName); // 原始文件名称
- string fileExtension = Path.GetExtension(fileName); // 文件扩展名
- //string saveName = Guid.NewGuid() + fileExtension; // 保存文件名称 这是个好方法。
- string saveName = Encrypt.GenerateOrderNumber() + fileExtension; // 保存文件名称 这是个好方法。
- file.SaveAs(uploadpath + saveName);
- return Json(new {
- Success = true,
- SaveName = path + saveName
- });
- }
- return Json(new {
- Success = false,
- Message = "请选择要上传的文件!"
- },
- JsonRequestBehavior.AllowGet);
- }
调用:
- <div class="page" id="upload">
- <h2>
- UploadImg
- </h2>
- <div id="dd" class="filePicker">
- 点击选择文件
- </div>
- <div id="preview">
- </div>
- </div>
- <script>
- $.fileUpload({
- filebutton: "#dd",
- previewZoom: "#preview"
- });
- </script>
扩展到 $ 对象而不扩展到 $.fn,是因为 zepto 中绑定事件的时候后者不方便,传递 id 或样式名容易绑定。手机端可以自动的调出相机和相册。默认是不预览的图片的, 需要制定预览区域,进度条需要自己写样式,只返回了进度值。
同时传 2 张的效果:
参考了两篇博客:
javascript html5 移动端轻松实现文件上传
html5 实现的文件上传预览功能
来源: http://www.jb51.net/article/111763.htm