批量上传js插件的使用案例

简介: 文件上传无疑是web应用中一个非常常用的功能,不管是PHP、jsp还是aspx、mvc等都会需要文件上传,但是众所周知当使用自带的文件上传功能时总会出现页面刷新的情况。



文件上传无疑是web应用中一个非常常用的功能,不管是PHP、jsp还是aspx、mvc等都会需要文件上传,但是众所周知当使用自带的文件上传功能时总会出现页面刷新的情况。当然现在有了html5这个好东西,我们可以调用它的新的api来做文件的异步上传。但是非常可惜,这个新的api并非每个浏览器都支持。



如果你会flash这当然很好,你可以自己写一个flash的上传插件来支持上传,不过本文不会对flash这个技术做任何的讨论。


好了言归正传,我们还是来讨论下只使用js的情况下如何才能异步无刷新的上传文件,首先估计大家会想到ajax,不过很不幸在目前没有html5支持的浏览器中使用ajax上传文件是不行的,而在国内使用支持html5浏览器的用户还不是绝大多数,那么这种方案只能放弃。


还有没有办法喃?当然有那就是使用iframe,看下面的html代码:

[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <body>  
  2.     <form action="WebForm1.aspx" target="dynamic_creation_upload_iframe" method="POST" enctype="multipart/form-data">  
  3.     <input type="file" name="upload1" />  
  4.     </form>  
  5.     <iframe name="dynamic_creation_upload_iframe"></iframe>  
  6. </body>  
这是一段我们经常使用的上传代码,如果你使用的是asp.net控件,它最终也会生成这样的html代码,其中的enctype就是指定需要上传文件的属性(action和method属性就不需要解释了吧)。不过在这个form上我添加了一个target属性,并且指定了它的值为下面那个iframe的name属性的值,这是为什么?其实很简单,就是当你提交这个form时(这样就开始了文件上传),等服务端接收到文件并保存成功响应客户端时,将响应的内容直接在这个iframe中刷新,这样这个iframe就起到了一个隔离的作用,此时我们只需要在这个iframe上绑定一个onload事件,那么当它刷新时这个事件将被触发,呵呵 我们就可以在这个load事件中做事情了(例如:在load的时候获取服务端响应的结果,从而得知上传是否成功)


有了这个思路事情就好办了,以下是根据这种思路构建的一个js插件

[javascript]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. /* 
  2.     无刷新异步上传插件 
  3.     2013-10-16 Devotion Created 
  4. */  
  5. (function ($) {  
  6.     var defaultSettings = {  
  7.         url: "",                                 //上传地址  
  8.         buttonFeature: true,                    //true:点击按钮时仅选择文件; false:选择完文件后立即上传  
  9.         fileSuffixs: ["jpg""png"],             //允许上传的文件后缀名列表  
  10.         errorText: "不能上传后缀为 {0} 的文件!"//错误提示文本,其中{0}将会被上传文件的后缀名替换  
  11.         onCheckUpload: function (text) { //上传时检查文件后缀名不包含在fileSuffixs属性中时触发的回调函数,(text为错误提示文本)  
  12.             alert(text);  
  13.         },  
  14.         onComplete: function (msg) { //上传完成后的回调函数[不管成功或失败,它都将被触发](msg为服务端的返回字符串)  
  15.         },  
  16.   
  17.   
  18.         onChosen: function (file, obj) { //选择文件后的回调函数,(file为选中文件的本地路径;obj为当前的上传控件实例)  
  19.             //alert(file);  
  20.         },  
  21.         maximumFilesUpload: 5,//最大文件上传数(当此属性大于1时,buttonFeature属性只能为true)  
  22.         onSubmitHandle: function (uploadFileNumber) { //提交上传时的回调函数,uploadFileNumber为当前上传的文件数量  
  23.             //在此回调中返回false上传提交将被阻止  
  24.             return true;  
  25.         },  
  26.         onSameFilesHandle: function (file) { //当重复选择相同的文件时触发  
  27.             //在此回调中返回false当前选择的文件将从上传队列中取消  
  28.             return true;  
  29.         },  
  30.         perviewImageElementId: "",//用于预览上传图片的元素id(请传入一个div元素的id)  
  31.   
  32.   
  33.         perviewImgStyle: null//用于设置图片预览时的样式(可不设置,在不设置的情况下多文件上传时只能显示一张图片),如{ width: '100px', height: '100px', border: '1px solid #ebebeb' }  
  34.     };  
  35.   
  36.   
  37.     $.fn.uploadFile = function (settings) {  
  38.   
  39.   
  40.         settings = $.extend({}, defaultSettings, settings || {});  
  41.   
  42.   
  43.         if (settings.perviewImageElementId) {  
  44.             //设置图片预览元素的必须样式  
  45.             if (!settings.perviewImgStyle) {  
  46.                 var perviewImg = document.getElementById(settings.perviewImageElementId);  
  47.                 perviewImg.style.overflow = "hidden";  
  48.             }  
  49.         }  
  50.   
  51.   
  52.         return this.each(function () {  
  53.             var self = $(this);  
  54.   
  55.   
  56.             var upload = new UploadAssist(settings);  
  57.   
  58.   
  59.             upload.createIframe(this);  
  60.   
  61.   
  62.             //绑定当前按钮点击事件  
  63.             self.bind("click"function (e) {  
  64.                 upload.chooseFile();  
  65.             });  
  66.   
  67.   
  68.             //将上传辅助类的实例,存放到当前对象中,方便外部获取  
  69.             self.data("uploadFileData", upload);  
  70.   
  71.   
  72.             //创建的iframe中的那个iframe,它的事件需要延迟绑定  
  73.             window.setTimeout(function () {  
  74.   
  75.   
  76.                 //为创建的iframe内部的iframe绑定load事件  
  77.                 $(upload.getIframeContentDocument().body.lastChild).on("load"function () {  
  78.                     var dcmt = upload.getInsideIframeContentDocument();  
  79.                     if (dcmt.body.innerHTML) {  
  80.   
  81.   
  82.                         if (settings.onComplete) {  
  83.                             settings.onComplete(dcmt.body.innerHTML);  
  84.                         }  
  85.   
  86.   
  87.                         dcmt.body.innerHTML = "";  
  88.                     }  
  89.                 });  
  90.             }, 100);  
  91.         });  
  92.     };  
  93. })(jQuery);  
  94.   
  95.   
  96. //上传辅助类  
  97. function UploadAssist(settings) {  
  98.     //保存设置  
  99.     this.settings = settings;  
  100.     //已选择文件的路径集合  
  101.     this.choseFilePath = [];  
  102.     //创建的iframe唯一名称  
  103.     this.iframeName = "upload" + this.getInputFileName();  
  104.     return this;  
  105. }  
  106.   
  107.   
  108. UploadAssist.prototype = {  
  109.     //辅助类构造器  
  110.     constructor: UploadAssist,  
  111.   
  112.   
  113.     //创建iframe  
  114.     createIframe: function (/*插件中指定的dom对象*/elem) {  
  115.   
  116.   
  117.         var html = "<html>"  
  118.                 + "<head>"  
  119.                 + "<title>upload</title>"  
  120.                 + "<script>"  
  121.                 + "function getDCMT(){return window.frames['dynamic_creation_upload_iframe'].document;}"  
  122.                 + "</" + "script>"  
  123.                 + "</head>"  
  124.                 + "<body>"  
  125.                 + "<form method='post' target='dynamic_creation_upload_iframe' enctype='multipart/form-data' action='" + this.settings.url + "'>"  
  126.                 + "</form>"  
  127.                 + "<iframe name='dynamic_creation_upload_iframe'></iframe>"  
  128.                 + "</body>"  
  129.                 + "</html>";  
  130.   
  131.   
  132.         this.iframe = $("<iframe name='" + this.iframeName + "'></iframe>")[0];  
  133.         this.iframe.style.width = "0px";  
  134.         this.iframe.style.height = "0px";  
  135.         this.iframe.style.border = "0px solid #fff";  
  136.         this.iframe.style.margin = "0px";  
  137.         elem.parentNode.insertBefore(this.iframe, elem);  
  138.         var iframeDocument = this.getIframeContentDocument();  
  139.         iframeDocument.write(html);  
  140.     },  
  141.   
  142.   
  143.     //获取上传控件名称  
  144.     getInputFileName: function () {  
  145.         return (new Date()).valueOf();  
  146.     },  
  147.   
  148.   
  149.     //创建上传控件到创建的iframe中  
  150.     createInputFile: function () {  
  151.         var that = this;  
  152.         var dcmt = this.getIframeContentDocument();  
  153.         var input = dcmt.createElement("input");  
  154.         input.type = "file";  
  155.         input.setAttribute("name""input" + this.getInputFileName());  
  156.         input.onchange = function () {  
  157.   
  158.   
  159.             var fileSuf = this.value.substring(this.value.lastIndexOf(".") + 1);  
  160.   
  161.   
  162.             //检查是否为允许上传的文件  
  163.             if (!that.checkFileIsUpload(fileSuf, that.settings.fileSuffixs)) {  
  164.                 that.settings.onCheckUpload(that.settings.errorText.replace("{0}", fileSuf));  
  165.                 return;  
  166.             }  
  167.   
  168.   
  169.             //选中后的回调  
  170.             that.settings.onChosen(this.value, this);  
  171.   
  172.   
  173.   
  174.   
  175.             if (that.checkFileIsExist(this.value)) {  
  176.                 //保存已经选择的文件路径  
  177.                 that.choseFilePath.push({ "name"this.name, "value"this.value });  
  178.                 var status = that.settings.onSameFilesHandle(this.value);  
  179.                 if (typeof status === "boolean" && !status) {  
  180.                     that.removeFile(this.value);  
  181.                     return;  
  182.                 }  
  183.             } else {  
  184.                 //保存已经选择的文件路径  
  185.                 that.choseFilePath.push({ "name"this.name, "value"this.value });  
  186.             }  
  187.   
  188.   
  189.             //是否开启了图片预览  
  190.             if (that.settings.perviewImageElementId) {  
  191.                 if (!that.settings.perviewImgStyle) {  
  192.                     perviewImage.beginPerview(this, that.settings.perviewImageElementId);  
  193.                 } else {  
  194.                     var ul = perviewImage.getPerviewRegion(that.settings.perviewImageElementId);  
  195.                     var main = perviewImage.createPreviewElement(this.value);  
  196.                     var li = document.createElement("li");  
  197.                     //li.style.float = "left";  
  198.                     if ($.browser.msie) {  
  199.                         li.style.styleFloat = "left";  
  200.                     }  
  201.                     else {  
  202.                         li.style.cssFloat = "left";  
  203.                     }  
  204.   
  205.   
  206.                     li.style.margin = "5px";  
  207.                     li.appendChild(main);  
  208.                     ul.appendChild(li);  
  209.                     var div = $(main).children("div").get(0);  
  210.                     $(main).children("img").hover(function () {  
  211.                         this.src = perviewImage.closeImg.after;  
  212.                     }, function () {  
  213.                         this.src = perviewImage.closeImg.before;  
  214.                     }).click(function () {  
  215.                         that.removeFile($(this).attr("filepath"));  
  216.                         $(this).parents("li").remove("li");  
  217.                     });  
  218.                     perviewImage.beginPerview(this, div, dcmt);  
  219.                 }  
  220.             }  
  221.   
  222.   
  223.             if (!that.settings.buttonFeature) {  
  224.                 that.submitUpload();  
  225.             }  
  226.         };  
  227.         dcmt.forms[0].appendChild(input);  
  228.         return input;  
  229.     },  
  230.   
  231.   
  232.     //获取创建的iframe中的document对象  
  233.     getIframeContentDocument: function () {  
  234.         return this.iframe.contentDocument || this.iframe.contentWindow.document;  
  235.     },  
  236.   
  237.   
  238.     //获取创建的iframe所在的window对象  
  239.     getIframeWindow: function () {  
  240.         return this.iframe.contentWindow || this.iframe.contentDocument.parentWindow;  
  241.     },  
  242.   
  243.   
  244.     //获取创建的iframe内部iframe的document对象  
  245.     getInsideIframeContentDocument: function () {  
  246.         return this.getIframeWindow().getDCMT();  
  247.     },  
  248.   
  249.   
  250.     //获取上传input控件  
  251.     getUploadInput: function () {  
  252.         var inputs = this.getIframeContentDocument().getElementsByTagName("input");  
  253.         var len = inputs.length;  
  254.   
  255.   
  256.         if (len > 0) {  
  257.             if (!inputs[len - 1].value) {  
  258.                 return inputs[len - 1];  
  259.             } else {  
  260.                 return this.createInputFile();  
  261.             }  
  262.         }  
  263.         return this.createInputFile();  
  264.     },  
  265.   
  266.   
  267.     //forEach迭代函数  
  268.     forEach: function (/*数组*/arr, /*代理函数*/fn) {  
  269.         var len = arr.length;  
  270.         for (var i = 0; i < len; i++) {  
  271.             var tmp = arr[i];  
  272.             if (fn.call(tmp, i, tmp) == false) {  
  273.                 break;  
  274.             }  
  275.         }  
  276.     },  
  277.   
  278.   
  279.     //提交上传  
  280.     submitUpload: function () {  
  281.         var status = this.settings.onSubmitHandle(this.choseFilePath.length);  
  282.         if (typeof status === "boolean") {  
  283.             if (!status) {  
  284.                 return;  
  285.             }  
  286.         }  
  287.         this.clearedNotChooseFile();  
  288.         var dcmt = this.getIframeContentDocument();  
  289.         dcmt.forms[0].submit();  
  290.     },  
  291.   
  292.   
  293.     //检查文件是否可以上传  
  294.     checkFileIsUpload: function (fileSuf, suffixs) {  
  295.   
  296.   
  297.         var status = false;  
  298.         this.forEach(suffixs, function (i, n) {  
  299.             if (fileSuf.toLowerCase() === n.toLowerCase()) {  
  300.                 status = true;  
  301.                 return false;  
  302.             }  
  303.         });  
  304.         return status;  
  305.     },  
  306.   
  307.   
  308.     //检查上传的文件是否已经存在上传队列中  
  309.     checkFileIsExist: function (/*当前上传的文件*/file) {  
  310.   
  311.   
  312.         var status = false;  
  313.         this.forEach(this.choseFilePath, function (i, n) {  
  314.             if (n.value == file) {  
  315.                 status = true;  
  316.                 return false;  
  317.             }  
  318.         });  
  319.         return status;  
  320.     },  
  321.   
  322.   
  323.     //清除未选择文件的上传控件  
  324.     clearedNotChooseFile: function () {  
  325.         var files = this.getIframeContentDocument().getElementsByTagName("input");  
  326.   
  327.   
  328.         this.forEach(files, function (i, n) {  
  329.             if (!n.value) {  
  330.                 n.parentNode.removeChild(n);  
  331.                 return false;  
  332.             }  
  333.         });  
  334.     },  
  335.   
  336.   
  337.     //将指定上传的文件从上传队列中删除  
  338.     removeFile: function (file) {  
  339.         var that = this;  
  340.         var files = this.getIframeContentDocument().getElementsByTagName("input");  
  341.         this.forEach(this.choseFilePath, function (i, n) {  
  342.             if (n.value == file) {  
  343.                 that.forEach(files, function (j, m) {  
  344.                     if (m.name == n.name) {  
  345.                         m.parentNode.removeChild(m);  
  346.                         return false;  
  347.                     }  
  348.                 });  
  349.                 that.choseFilePath.splice(i, 1);  
  350.                 return false;  
  351.             }  
  352.         });  
  353.     },  
  354.   
  355.   
  356.     //清空上传队列  
  357.     clearUploadQueue: function () {  
  358.         this.choseFilePath.length = 0;  
  359.         this.getIframeContentDocument().forms[0].innerHTML = "";  
  360.     },  
  361.   
  362.   
  363.     //选择上传文件  
  364.     chooseFile: function () {  
  365.         var uploadfile;  
  366.         if (this.choseFilePath.length == this.settings.maximumFilesUpload) {  
  367.             if (this.settings.maximumFilesUpload <= 1) {  
  368.                 this.choseFilePath.length = 0;  
  369.                 var files = this.getIframeContentDocument().getElementsByTagName("input");  
  370.                 if (!files.length) {  
  371.                     uploadfile = this.getUploadInput();  
  372.                     $(uploadfile).click();  
  373.                     return;  
  374.                 } else {  
  375.                     uploadfile = files[0];  
  376.                     $(uploadfile).click();  
  377.                     return;  
  378.                 }  
  379.             } else {  
  380.                 return;  
  381.             }  
  382.         }  
  383.         uploadfile = this.getUploadInput();  
  384.         $(uploadfile).click();  
  385.     }  
  386. };  
  387.   
  388.   
  389. //图片预览操作  
  390. var perviewImage = {  
  391.     timers: [],  
  392.     closeImg: {  
  393.         before: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAOVSURBVHjaYtTUdGdAA4K/fv3U+Pv3rw+QLfT//3+Gf//+vWNiYtjCwsJyAyj2HiT2//8/sGKAAGJB1gkU9Pj581eNnJyctaamMgM/Py8DIyMDw+fPXxlu3rxfdfPmjaPMzIwtTEzMO2B6AAKIBaH5fw4LC1tHeHgQt7u7PYOOjhIDNzcb2IBfv/4x3LjxiGHr1n3WK1duXPPx45sKJiamKSB9AAHECPIC0GZ3ZmbWzQkJkazu7rYMLCyMDD9//gYZCzWcgYGVlRUozsxw9Oh5hv7+Gb8/fXrnC+TvBAggZhERZb7fv3/PdnCwV7C3twT69w+DlpYcw5s3HxkeP34FdP53IPsDg6qqNAMXFxvQIA4GoGXMFy9eVgK6eg1AADH9/ftbW0hIxEpFRQms0MBAlYGDg51BQ0OegZ2dneH58zdAMRUGKSlhBnFxQYY7dx4CvfSHQVBQyAqkFyCAmIWEFDOlpaVtgQHH8O7dB4aXLz8wqKjIMHBysoE1SUqKMCgoSIC90te3lGHNmu0MDx8+Yfjx4xvQmz9eAgQQCzAwhBiBIfX69RugwC+GR4+eAl3yliEx0Y+Bl5eDQU5ODBwG3d0LGdau3QH0AjMwLFiBruQEBjCTEEAAsYBC+du3HwxPnjxnAMY90JCfoLBlePXqLdAAabDNX778AHvl37+/QP9DYubfP0haAAggJlAi+fr1M8Pbt2+Bml4z8PBwMxQURDMoK0uDbf78+QfYJY2N2Qy2thZA//8CGsIMtOg70MI/7wACiAkYkluAfmH48+cPMOHwMbS1FTJoaspB/bwYqHE6w4cP3xn4+DgYWltzgAGqywCMNbABQBdsAQggJmAsX/3+/esxkPNAoX7jxgNQomKYMWMtw65dRxkuXLjGMHHiEobv338x3Lv3DEhDLAO6+hjQq1cBAohRWdkOqOGvOwcHz2Z1dU1WcXEJBgkJYYbbtx+AExIogH/9+s2gra0KDOgPwLTxmOHKlfO/v3z55AtM0jsBAggYjfKg0Lz769eP958/f7FnZ2djAyYUBhERQWBUcgLDhItBWFiY4f37j8AYeshw/frVr1++fCwFal4O8iZAAIENAKdpRoZTwLg99/Llc8VPnz7JffnyFWQwMAa+Mdy/fw+YmW4w3Lp1/eiPH19zgJqXwfIQQACBvQDNiaBsC/K/IDCQNICKfNjYWIVAYQNMH++AIb4FGPrg7IycgwECDADIUZC5UWvTuwAAAABJRU5ErkJggg==",  
  394.         after: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAA3XAAAN1wFCKJt4AAAAB3RJTUUH1wwbFhkQHxvdFgAAArpJREFUeNplz1to1QUAx/HP/3/O2c7OrudsR8vmamOL2hw5LaQHgxKCLvQSRVgPFhJKo4cyMsmxKNQgfOuhfKxICQTpocvAIFhai/WSTNIcnK3pbu12tnO2cwsfbZ+H3+MXfgGbfURDgn0xHgiIFskUuPgOE/7njsBxahsYqAnDN1p3765N9/QIYzGL4+Myw8PlbC53fp23j5HZFBhgSxPft27f3tfX36+ure2O+sbKiitnzrg2MjK/xjNH+RUCeJbo41xsSyb3PtR/WLQuLhIGVAJKlEsUSyUBrp8966+xsdkl+o7zTwiP8mqSvffu6ZMLs+565YAVWRvL1xSWrpufvmHr/v3y1dVu30pHIuk4pxCEiCQ4nIyEYk15heakmm3bdR06Zrq0LjM3ruPNI+o7O8V7uy1NTkjV10vw4ns0Rw6Q7uCTdLwS1LfMyM+Mytxa0r73aVse2adp52Oau7pd/eGCq4MHNUxPKc4sy1dEylwOt3FPNUH09gTrWhILSr+d9N3pQfGGpHRXjz9/+tHoqRe0t8yqasyK1lKNKlrDdYpVCEqUixRLLBZTep98DkD7zofFO3pVGqlqJlJDDDEK4TkmQlbXc+QWGZ9P2TMwpHXHLpnL541+dVRtMuWp00NmGncpxCkUCLDGWDjJWp6LG0XmJtn6xOu2PrjLzUvn3fr6JdVXP3btmyNqGlN2vHbC/Dxry5SZ+pTfIyh3MN3Jyxt54cKVYYXVKZPn3peIFkTK5G5ckp34W+bLE7IjeWGOOT78gp8DQPwzBtt5dymkkqTmbuIpYnUEAblZsldIrLLB0AGeX2QlAEDD5xy7n7eWia2GlKsREhaIb9CEZS58wKFRplGJAGD9W36JMXwf9cmKdF1RIlGgrmS1zOU/GDjIyZv8iwoENguRQKqblnqiI8yUWUAWJQD4D4Cg/5i7WltRAAAAAElFTkSuQmCC"  
  395.     },  
  396.   
  397.   
  398.     //获取预览元素  
  399.     getElementObject: function (elem) {  
  400.         if (elem.nodeType && elem.nodeType === 1) {  
  401.             return elem;  
  402.         } else {  
  403.             return document.getElementById(elem);  
  404.         }  
  405.     },  
  406.     //开始图片预览  
  407.     beginPerview: function (/*文件上传控件实例*/file, /*需要显示的元素id或元素实例*/perviewElemId,dcmt) {  
  408.         for (var t = 0; t < this.timers.length; t++) {  
  409.             window.clearInterval(this.timers[t]);  
  410.         }  
  411.         this.timers.length = 0;  
  412.   
  413.   
  414.         var preview_div = this.getElementObject(perviewElemId);  
  415.   
  416.   
  417.         var MAXWIDTH = preview_div.clientWidth;  
  418.         var MAXHEIGHT = preview_div.clientHeight;  
  419.   
  420.   
  421.         if (file.files && file.files[0]) { //此处为Firefox,Chrome以及IE10的操作  
  422.             preview_div.innerHTML = "";  
  423.             var img = document.createElement("img");  
  424.             preview_div.appendChild(img);  
  425.             img.style.visibility = "hidden";  
  426.             img.onload = function () {  
  427.                 var rect = perviewImage.clacImgZoomParam(MAXWIDTH, MAXHEIGHT, img.offsetWidth, img.offsetHeight);  
  428.                 img.style.width = rect.width + 'px';  
  429.                 img.style.height = rect.height + 'px';  
  430.                 img.style.marginLeft = rect.left + 'px';  
  431.                 img.style.marginTop = rect.top + 'px';  
  432.                 img.style.visibility = "visible";  
  433.             }  
  434.   
  435.   
  436.             var reader = new FileReader();  
  437.             reader.onload = function (evt) {  
  438.                 img.src = evt.target.result;  
  439.             }  
  440.             reader.readAsDataURL(file.files[0]);  
  441.         }  
  442.         else {//此处为IE6,7,8,9的操作  
  443.             file.select();  
  444.             var src = dcmt.selection.createRange().text;  
  445.   
  446.   
  447.             var div_sFilter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod='scale',src='" + src + "')";  
  448.             var img_sFilter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod='image',src='" + src + "')";  
  449.   
  450.   
  451.             preview_div.innerHTML = "";  
  452.             var img = document.createElement("div");  
  453.             preview_div.appendChild(img);  
  454.             img.style.filter = img_sFilter;  
  455.             img.style.visibility = "hidden";  
  456.             img.style.width = "100%";  
  457.             img.style.height = "100%";  
  458.   
  459.   
  460.             function setImageDisplay() {  
  461.                 var rect = perviewImage.clacImgZoomParam(MAXWIDTH, MAXHEIGHT, img.offsetWidth, img.offsetHeight);  
  462.                 preview_div.innerHTML = "";  
  463.                 var div = document.createElement("div");  
  464.                 div.style.width = rect.width + 'px';  
  465.                 div.style.height = rect.height + 'px';  
  466.                 div.style.marginLeft = rect.left + 'px';  
  467.                 div.style.marginTop = rect.top + 'px';  
  468.                 div.style.filter = div_sFilter;  
  469.                 preview_div.appendChild(div);  
  470.             }  
  471.   
  472.   
  473.             //图片加载计数  
  474.             var tally = 0;  
  475.   
  476.   
  477.             var timer = window.setInterval(function () {  
  478.                 if (img.offsetHeight != MAXHEIGHT) {  
  479.                     window.clearInterval(timer);  
  480.                     setImageDisplay()  
  481.                 } else {  
  482.                     tally++;  
  483.                 }  
  484.                 //如果超过两秒钟图片还不能加载,就停止当前的轮询  
  485.                 if (tally > 20) {  
  486.                     window.clearInterval(timer);  
  487.                     setImageDisplay()  
  488.                 }  
  489.             }, 100);  
  490.   
  491.   
  492.             this.timers.push(timer);  
  493.         }  
  494.     },  
  495.     //按比例缩放图片  
  496.     clacImgZoomParam: function (maxWidth, maxHeight, width, height) {  
  497.         var param = { width: width, height: height };  
  498.         if (width > maxWidth || height > maxHeight) {  
  499.             var rateWidth = width / maxWidth;  
  500.             var rateHeight = height / maxHeight;  
  501.   
  502.   
  503.             if (rateWidth > rateHeight) {  
  504.                 param.width = maxWidth;  
  505.                 param.height = Math.round(height / rateWidth);  
  506.             } else {  
  507.                 param.width = Math.round(width / rateHeight);  
  508.                 param.height = maxHeight;  
  509.             }  
  510.         }  
  511.   
  512.   
  513.         param.left = Math.round((maxWidth - param.width) / 2);  
  514.         param.top = Math.round((maxHeight - param.height) / 2);  
  515.         return param;  
  516.     },  
  517.     //创建预览元素  
  518.     createPreviewElement: function (/*上传时的文件名*/file, /*预览时的样式*/style) {  
  519.         style = style || { width: '100px', height: '100px', border: '1px solid #ebebeb' };  
  520.         var img = document.createElement("div");  
  521.         img.title = file;  
  522.         img.style.overflow = "hidden";  
  523.         for (var s in style) {  
  524.             img.style[s] = style[s];  
  525.         }  
  526.         var text = document.createElement("div");  
  527.         text.style.width = style.width;  
  528.         text.style.overflow = "hidden";  
  529.         text.style.textOverflow = "ellipsis";  
  530.         text.style.whiteSpace = "nowrap";  
  531.         text.innerHTML = file;  
  532.   
  533.   
  534.   
  535.   
  536.         var top = 0 - window.parseInt(style.width) - 15;  
  537.         var right = 0 - window.parseInt(style.width) + 14;  
  538.         var close = document.createElement("img");  
  539.         close.setAttribute("filepath", file);  
  540.         close.src = this.closeImg.before;  
  541.         close.style.position = "relative";  
  542.         close.style.top = top + "px";  
  543.         close.style.right = right + "px";  
  544.         close.style.cursor = "pointer";  
  545.   
  546.   
  547.         var main = document.createElement("div");  
  548.         main.appendChild(img);  
  549.         main.appendChild(text);  
  550.         main.appendChild(close);  
  551.         return main;  
  552.     },  
  553.   
  554.   
  555.     //获取预览区域  
  556.     getPerviewRegion: function (elem) {  
  557.         var perview = $(this.getElementObject(elem));  
  558.         if (!perview.find("ul").length) {  
  559.             var ul = document.createElement("ul");  
  560.             ul.style.listStyleType = "none";  
  561.             ul.style.margin = "0px";  
  562.             ul.style.padding = "0px";  
  563.   
  564.   
  565.             var div = document.createElement("div");  
  566.             div.style.clear = "both";  
  567.             perview.append(ul).append(div);  
  568.             return ul;  
  569.         } else {  
  570.             return perview.children("ul").get(0);  
  571.         }  
  572.     }  
  573. }  


看看这个插件中的那个createIframe方法,对它做一点解释
[javascript]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. //创建iframe  
  2.     createIframe: function (/*插件中指定的dom对象*/elem) {  
  3.   
  4.         var html = "<html>"  
  5.                 + "<head>"  
  6.                 + "<title>upload</title>"  
  7.                 + "<script>"  
  8.                 + "function getDCMT(){return window.frames['dynamic_creation_upload_iframe'].document;}"  
  9.                 + "</" + "script>"  
  10.                 + "</head>"  
  11.                 + "<body>"  
  12.                 + "<form method='post' target='dynamic_creation_upload_iframe' enctype='multipart/form-data' action='" + this.settings.url + "'>"  
  13.                 + "</form>"  
  14.                 + "<iframe name='dynamic_creation_upload_iframe'></iframe>"  
  15.                 + "</body>"  
  16.                 + "</html>";  
  17.   
  18.         this.iframe = $("<iframe name='" + this.iframeName + "'></iframe>")[0];  
  19.         this.iframe.style.width = "0px";  
  20.         this.iframe.style.height = "0px";  
  21.         this.iframe.style.display = "none";  
  22.   
  23.         elem.parentNode.insertBefore(this.iframe, elem);  
  24.         var iframeDocument = this.getIframeContentDocument();  
  25.         iframeDocument.write(html);  
  26.     },  
大家应该都看到了这个方法中有一个html变量,它保存的其实就是文章开头的那段html。在这段html中我添加了一个function名为getDCMT的函数,这是为了获取名为dynamic_creation_upload_iframe的iframe所在的document对象。在form中我也去掉了文件上传的input控件,这是因为我将动态创建input控件到这个form中,并且我会将这段html使用js的方式把它添加到一个动态创建的iframe中。为什么要这样呢?呵呵 我想聪明的你一定会明白的!


好了插件做好了,我们如何来使用呢?


首先 将那段插件js代码保存为notRefreshFilesUpload.js的文件,方便在页面上的引用,然后构建包含如下结构的page

[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <!DOCTYPE html>  
  2. <html xmlns="http://www.w3.org/1999/xhtml">  
  3. <head>  
  4. <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>  
  5.     <title>files upload</title>  
  6.     <script src="Scripts/jquery-1.7.1.min.js"></script>  
  7.     <script src="Scripts/notRefreshFilesUpload.js"></script>  
  8.     <script>  
  9.         $(function () {  
  10.   
  11.             var btn = $("#Button1");  
  12.   
  13.             btn.uploadFile({  
  14.                 url: "WebForm1.aspx",  
  15.                 fileSuffixs: ["jpg", "png", "gif"],  
  16.                 buttonFeature: true,  
  17.                 errorText: "{0}",  
  18.                 maximumFilesUpload: 5,//最大文件上传数  
  19.                 onComplete: function (msg) {  
  20.                     $("#testdiv").html(msg);  
  21.                 },  
  22.                 perviewImageElementId: "fileList", //设置预览图片的元素id  
  23.                 perviewImgStyle: { width: '100px', height: '100px', border: '1px solid #ebebeb' }//设置预览图片的样式  
  24.             });  
  25.   
  26.             var upload = btn.data("uploadFileData");  
  27.   
  28.             $("#files").click(function () {  
  29.                 upload.submitUpload();  
  30.             });  
  31.         });  
  32.     </script>  
  33.   
  34. </head>  
  35.     <body>  
  36.           
  37.           
  38.         <div style="width: 400px; height: 300px; float:left">  
  39.             <input id="Button1" type="button" value="选择文件" />  
  40.             <input id="files" type="button" value="上传" />  
  41.             <div id="fileList" style="margin-top: 10px; padding-top:10px; border-top:1px solid #C0C0C0;font-size: 13px; width:400px">  
  42.                   
  43.             </div>  
  44.         </div>  
  45.         <div id="testdiv"></div>  
  46.     </body>  
  47. </html>  


上面的代码中已经包含了图片预览的功能,使用非常简单我就不多言了,只需要给定用于显示图片的元素id即可,一般用div作为图片预览的元素。

这是服务端的方法,在这里我使用了aspx作为服务端的接收方式,当然你可以换成其他任何语言或形式作为服务端的处理方案(可以是php、jsp、mvc等等)
[csharp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. public partial class WebForm1 : System.Web.UI.Page  
  2. {  
  3.     protected void Page_Load(object sender, EventArgs e)  
  4.     {  
  5.         List<string> filenames = new List<string>();  
  6.   
  7.         HttpFileCollection files = Request.Files;  
  8.   
  9.         for (int i = 0; i < files.Count; i++)  
  10.         {  
  11.             filenames.Add(files[i].FileName);  
  12.         }  
  13.   
  14.         Response.Write(string.Join("___", filenames));  
  15.         Response.Flush();  
  16.         Response.End();  
  17.     }  
  18. }  
服务端代码为多文件上传处理的方式,呵呵 也就是说这个插件也是支持多文件上传的,在服务端的代码中我仅仅返回了上传文件的名称作为对客户端的响应,当然你可以返回任何你希望的形式,你只需要在客户端用js做相应处理即可(即在插件的complete这个回调中处理响应,它其中的msg回调参数将把服务端的响应结果回传给你)。


好了 一个兼容各种浏览器,并且支持图片预览和无刷新异步上传的纯js插件就搞定了。上个图看看效果
相关文章
|
10天前
|
JavaScript 前端开发
js变量的作用域、作用域链、数据类型和转换应用案例
【4月更文挑战第27天】JavaScript 中变量有全局和局部作用域,全局变量在所有地方可访问,局部变量只限其定义的代码块。作用域链允许变量在当前块未定义时向上搜索父级作用域。语言支持多种数据类型,如字符串、数字、布尔值,可通过 `typeof` 检查类型。转换数据类型用 `parseInt` 或 `parseFloat`,将字符串转为数值。
17 1
|
15天前
|
JavaScript
浏览器插件crx文件--JS混淆与解密
浏览器插件crx文件--JS混淆与解密
19 0
|
2月前
|
JavaScript 计算机视觉
纯js实现人脸识别眨眨眼张张嘴案例——ccv.js
纯js实现人脸识别眨眨眼张张嘴案例——ccv.js
51 0
|
2月前
|
JavaScript 前端开发 Java
纯前端JS实现人脸识别眨眨眼张张嘴案例
纯前端JS实现人脸识别眨眨眼张张嘴案例
56 0
|
3月前
|
JavaScript 前端开发 安全
使用 Node.js 插件给指定目录下的所有图片添加上文字水印
使用 Node.js 插件给指定目录下的所有图片添加上文字水印
63 0
|
2月前
|
JavaScript 计算机视觉
纯js实现人脸识别眨眨眼张张嘴案例——alive_face.js
纯js实现人脸识别眨眨眼张张嘴案例——alive_face.js
23 0
|
1天前
|
JavaScript
js的插件
js的插件
5 1
|
10天前
|
JavaScript 前端开发
js的let、const、var的区别以及应用案例
【4月更文挑战第27天】ES6 中,`let` 和 `const` 是新增的变量声明关键字,与 `var` 存在显著差异。`let` 允许重新赋值,而 `const` 不可,且两者都具有块级作用域。`var` 拥有函数级作用域,并可在函数内任意位置访问。`let` 和 `const` 声明时必须初始化,而 `var` 不需。根据需求选择使用:局部作用域用 `let`/`const`,全局或函数范围用 `var`,不可变值用 `const`。
19 2
|
13天前
android-agent-web中js-bridge案例
android-agent-web中js-bridge案例
20 2
|
15天前
|
JSON 前端开发 JavaScript
【2024-04-22 源码】最新PDF批注注释插件库,pdf.js插件库,纯前端离线JavaScript库(PDF高亮、下划线、橡皮擦、文本框、画笔、历史记录)
一款基于 pdf.js 开发的PDF批注插件库,支持纯离线内网部署,功能完善、强大且在不断升级,极易上手,欢迎关注!
33 4
【2024-04-22 源码】最新PDF批注注释插件库,pdf.js插件库,纯前端离线JavaScript库(PDF高亮、下划线、橡皮擦、文本框、画笔、历史记录)