定制jQuery File Upload為微博式單文件上傳

原文鏈接:http://avnpc.com/pages/single-file-upload-component-by-jquery-file-upload


jQuery File Upload是一個非常優秀的上傳組件,主要使用了XHR作為上傳方式,并且利用了相當多的現代瀏覽器功能,所以可以實現諸如批量上傳、超大文件上傳、圖片預覽、拖拽上傳、上傳進度顯示、跨域上傳等功能。

美中不足的是jQuery File Upload的默認UI比較復雜,集成了全部功能,讓jQuery File Upload的定制變得比較繁瑣。

嘗試用jQuery File Upload制作了一個類似微博圖片上傳的單文件式上傳Demo,將一些要點記錄下來備忘。最終效果如下圖:

jQuery File Upload Demo

jQuery File Upload的最簡模型

jQuery File Upload包含了一堆文件,首先需要弄清楚的是最核心的部分是哪些,根據官方的例子可以知道,一個最簡單的jQuery File Upload上傳組件,必須包括以下文件:

  • jQuery核心庫,建議使用jQuery 1.8以上版本
  • js/vendor/jquery.ui.widget.js : jQuery UI Widget
  • js/jquery.iframe-transport.js : 擴展iframe數據傳輸
  • js/jquery.fileupload.js : jQuery File Upload核心類
  • js/cors/jquery.xdr-transport.js 在IE下應載入此文件解決跨域問題

此時只需要加載一個上傳按鈕

<input id="fileupload" type="file" name="files[]" data-url="server/php/" multiple>

以及一行代碼

$('#fileupload').fileupload();

就完成了一個最基本的上傳組件。這個最簡單的上傳組件可以將選中的文件以表單形式提交到data-url約定的URL,同時提供了足夠多的設置和基礎事件可供擴展。

jQuery File Upload的簡單擴展

對于最簡模型,稍加擴展就可以實現一些比較常用的功能,比如可以在上傳完畢后可以顯示一個簡單的結果:

$('#fileupload').fileupload({done: function (e, data) {$.each(data.result, function (index, file) {$('<p/>').text(file.name + ' uploaded').appendTo($("body"));});}
});

或者顯示上傳進度,配合一些進度條組件就可以構成一個上傳進度條

$('#fileupload').fileupload('option', {progressall: function (e, data) {var progress = parseInt(data.loaded / data.total * 100, 10);console.log(progress + '%');}
});

等等。只要多閱讀手冊就可以配合項目做更具體的擴展開發。

XHR響應為Json時IE的下載BUG

這里需要特別注意的是,由于jQuery File Upload都是采用XHR在傳遞數據,服務器端返回的通常是JSON格式的響應,但是IE會將這些JSON響應誤認為是文件傳輸,然后直接彈出下載框詢問是否需要下載。

解決這個問題的方法是必須將相應的Http Head從

Content-Type: application/json

更改為

Content-Type: text/plain

具體的實現根據服務端不同有所區別,比如ZF2中可以在Controller中這樣寫:

 $this->getServiceLocator()->get('Application')->getEventManager()->attach(\Zend\Mvc\MvcEvent::EVENT_RENDER, function($event){$event->getResponse()->getHeaders()->addHeaderLine('Content-Type', 'text/plain');}, -10000);

這也是我在stackoverflow上的對ZF2更改最終響應類型的一個回答

jQuery File Upload UI的構成與說明

為了引入更多功能,jQuery File Upload在上面最簡模型的基礎上又實現了一套jQuery File Upload UI,也就是官方給出的最終Demo,這套UI額外提供了以下功能:

  • 最大/最小文件限定 Options.maxFileSize / Options.mixFileSize
  • 文件類型限定,通過正則表達式檢測文件名實現 Options.acceptFileTypes
  • 選擇文件后自動上傳 Options.autoUpload
  • 上傳文件數量限制,通過上傳后將選擇文件按鈕置為Disabled實現 Options.maxNumberOfFiles
  • 上傳模板,就是選擇文件后顯示預覽的html代碼 Options.uploadTemplate
  • 下載模板,當文件上傳完畢后顯示的html代碼 Options.downloadTemplate

等等,同時還增加了一系列新的接口和事件,具體都可以查閱官方手冊。

具體對應到文件為:

  • JavaScript-Templates : JS模板引擎
  • JavaScript-Load-Image : 圖片預覽功能
  • js/jquery.fileupload-ui.js & css/jquery.fileupload-ui.css : UI核心類,CSS可以替換舊式的上傳控件為統一的按鈕
  • js/jquery.fileupload-fp.js:進度條擴展功能

也許正是因為附加功能太多,各功能之間耦合非常重,jQuery File Upload UI顯得不夠友好,主要體現在:

  • 上述功能均無法拆分,必須統一全部加載
  • 各功能需要界面存在相應元素,如果缺少某些元素,包括JS模板內的元素,整個UI無法正常工作
  • JS模板引擎對標簽配對非常嚴格,標簽如果遺漏也有可能引起UI無法正常工作

所以經驗之談是,在定制jQuery File Upload UI時,如果UI無法工作。首先檢查js文件是否全部加載,然后檢查頁面元素是否齊全,再次檢查JS模板標簽是否嚴格配對,最后還可以查看頁面是否有重復調用fileupload()方法。

jQuery File Upload UI構成元素

UI的部件都是硬編碼的HTML class,無法更改。核心的幾個部件為

全局控制按鈕 (必須)

    <div class="fileupload-buttonbar"><span class="fileinput-button"><input type="file" name="files[]" multiple></span><button type="submit" class="start">Start upload</button><button type="reset" class="cancel">Cancel upload</button><button type="button" class="delete">Delete</button><input type="checkbox" class="toggle"></div>

最外層容器為.fileupload-buttonbar,內部包含

  • 文件選擇按鈕 .fileinput-button (必須),內部必須包裹一個input:file
  • 開始上傳按鈕 .start
  • 取消上傳按鈕 .cancel
  • 刪除按鈕 .delete
  • 文件勾選按鈕 .toggle

整體上傳進度 (可選)

<div class="fileupload-progress"><div class="progress"><div class="bar" style="width:0%;"></div></div><div class="progress-extended"></div>
</div>

最外層容器為.fileupload-progress,內部包含

  • 上傳進度條容器.progress
  • 上傳進度條 .bar
  • 上傳進度文本 .progress-extended

文件顯示容器 (必須)

<div class="files"></div>

.file容器是最重要的UI部件,上傳時的文件預覽模板以及上傳完畢后的文件顯示模板都將顯示在這里。

文件預覽模板 (必須)

<script id="template-upload" type="text/x-tmpl">
{% for (var i=0, file; file=o.files[i]; i++) { %}
<div class="template-upload">{% if (file.error) { %}<div class="error">{%=file.error%}</div>{% } else { %}<div class="preview"><span class="fade"></span></div><div class="name"><span>{%=file.name%}</span></div><div class="size"><span>{%=o.formatFileSize(file.size)%}</span></div><div class="progress progress-success progress-striped active" role="progressbar" aria-valuemin="0" aria-valuemax="100" aria-valuenow="0" style="height:5px;"><div class="bar" style="width:0%;"></div></div><span class="start">{% if (!o.options.autoUpload) { %}<button>Start Upload</button>{% } %}</span>{% } %}<span class="cancel"><button>Cancel</button></span>
</div>
{% } %}
</script>

這部分邏輯不難讀懂,由于文件選擇是多選的,所以被選擇文件一開始以數組方式存放,循環輸出。即使我們加入最大文件只能上傳一個,這里得到的仍然是數組形式。

當文件有任何錯誤時,如文件類型被禁止,文件大小不符合約定,會得到file.error。文件檢測沒有問題,則可以用以下元素控制當前文件:

  • 開始上傳當前文件按鈕.start (必須)
  • 取消上傳當前文件按鈕.cancel (可選)
  • 當前文件上傳進度.progress (可選)

上傳后文件回調顯示模板 (必須)

<script id="template-download" type="text/x-tmpl">
{% for (var i=0, file; file=o.files[i]; i++) { %}
<div class="template-download">{% if (file.error) { %}<div class="error">{%=file.error%}</div><span class="cancel"><button class="btn btn-block"><i class="icon-ban-circle"></i>Cancel</span>{% } else { %}<div class="preview"><img src="{%=file.thumbnail_url%}"></div><div class="name"><span>{%=file.name%}</span></div><div class="size"><span>{%=o.formatFileSize(file.size)%}</span></div><div class="delete"><button data-type="{%=file.delete_type%}" data-url="{%=file.delete_url%}">Delete</button></div>{% } %}
</div>
{% } %}
</script>

這一部分的o.files完全來自服務器端的json響應,所以模板內容可以自由發揮。唯一被定制的元素為刪除按鈕.delete。 點擊這個按鈕會向按鈕中指定的url發送請求,比如

<div class="delete"><button data-type="DELETE" data-url="/file/1">Delete</button></div>

點擊后則會用DELETE方式發送HTTP請求

DELETE /file/1

jQuery File Upload UI工作流程

有了上面羅列的UI元素,就可以拼湊出一個簡單的jQuery File Upload UI工作流程:

  1. 用戶點擊.fileinput-button選擇要上傳的文件(多個)
  2. 文件選擇后,文件信息被整理為數組置入文件預覽模板#template-upload
  3. 模板引擎循環處理文件信息并生成模板.template-upload
  4. 每生成一個模板,模板就被插入到文件顯示容器.files的最后。
  5. 用戶點擊上傳按鈕.start上傳,文件信息被轉換為XHR請求至服務器端
  6. UI獲得服務器端生成JSON響應文件
  7. JSON響應信息也被整理成數組置入回調顯示模板#template-download
  8. 模板引擎循環處理文件信息并生成模板.template-download
  9. 每生成一個模板,會將此模板替換對應的.template-upload部分

定制過程

有了上面的基礎,要個性化的定制jQuery File Upload就簡單了很多:

限制文件類型

由于沒有使用Flash空間,上傳的文件選擇框是無法限制文件類型的,所以所謂的限制文件類型,只能讓用戶選擇文件之后,用file.error顯示一個錯誤信息。例如本次需要限定可上傳的文件為圖片,那么Options指定:

acceptFileTypes:  /(\.|\/)(gif|jpe?g|png)$/i

即可。

在Google Chrome瀏覽器中,可以用input:file原生支持文件類型限定,可以配合使用:

<input type="file" name="upload[]"  accept="image/png, image/gif, image/jpg, image/jpeg">

不過在客戶端做再多的限定也只是提升用戶體驗,不能真正保證安全性,所以不要忘記了在服務器端做同樣的類型檢測。

文件數量限制

只需在Options指定

maxNumberOfFiles : 1

即可。jQuery File Upload UI的處理方式是當用戶上傳一個文件后,文件選擇按鈕被置為Disabled。

這同樣只是客戶端的小把戲,真正想要嚴格的約束用戶只能上傳一個文件還是需要在服務器端通過Session做更加復雜的控制。

文件大小限制

Options中指定

maxFileSize: 5000000

即只允許單文件最大5MB。

Firefox disable bug

在Firefox環境下測試是,發現如果將文件數量限制為1,選擇一次文件,刷新頁面之后文件選擇按鈕會莫名其妙的被加上一個Disabled屬性,導致無法點擊。所以最終我們的初始化代碼為:

var uploader = $("#fileupload");
uploader.fileupload({dataType: 'json',autoUpload: false,acceptFileTypes:  /(\.|\/)(gif|jpe?g|png)$/i,maxNumberOfFiles : 1,maxFileSize: 5000000 
});
uploader.find("input:file").removeAttr('disabled');

最后就是界面的一些調整,完整代碼在EvaEngine的File模塊下,點擊查看.

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/276693.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/276693.shtml
英文地址,請注明出處:http://en.pswp.cn/news/276693.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

vb趣味編程彈球小游戲_最好玩的微信小游戲集合,總有一款是你沒玩過的

大家好&#xff0c;這里是小雅龍生活趣味時間&#xff0c;自從17年微信推出小游戲程序以來&#xff0c;微信小游戲行業可謂是炙手可熱&#xff0c;知道2019年不斷有許許多多的微信小游戲如雨后春筍般的生根發芽。下面就由我帶大家來看看今年最好玩&#xff0c;最受歡迎的微信小…

開發MOSS2007 Masterpage的一些經驗

一直在做MOSS平臺的Masterpage開發,碰到很多的問題,總結了一些經驗,特此記錄: masterpage的所有的ContentPlaceholder詳細解釋見以下網址:http://www.cnblogs.com/WinYoung/archive/2007/06/25/791766.html 1.如果應用masterpage以后IE狀態欄出現""網頁指令碼錯誤訊息…

Golang——垃圾回收GC(2)

1 垃圾回收中的重要概念 1.1 定義 In computer science, garbage collection (GC) is a form of automatic memory management. The garbage collector, or just collector, attempts to reclaim garbage, or memory occupied by objects that are no longer in use by the pro…

java gui框架_推薦!程序員整理的Java資源大全

構建這里搜集了用來構建應用程序的工具。Apache Maven&#xff1a;Maven使用聲明進行構建并進行依賴管理&#xff0c;偏向于使用約定而不是配置進行構建。Maven優于Apache Ant。后者采用了一種過程化的方式進行配置&#xff0c;所以維護起來相當困難。Gradle&#xff1a;Gradle…

帆軟報表(finereport)控件背景色更改

setTimeout(function() {$(.fr-trigger-btn-up).css({"background-color": "#003399" });}, 100); 轉載于:https://www.cnblogs.com/Williamls/p/11571586.html

開心網分析,師從“中國緣”

作者&#xff1a;麥田   一&#xff0c;師從“中國緣” 開心網從08年“爆發”之后&#xff0c;網上出現很多評論文章。幾乎100%的評論文章都談到了開心網“不可思議”的爆發增長速度&#xff0c;比如幾個月就進入了alexa前500等等。但是&#xff0c;幾乎沒有一篇文章提到“開心…

HTML5+CSS3+JQuery1.9 輸入框切換和Div失焦模擬

Div失焦原理&#xff1a;判斷document點擊對象是否在Div容器以內&#xff0c;否則觸發事件 需要腳本&#xff1a;jquery-1.9.1.js 下載地址&#xff1a;http://download.csdn.net/detail/dmtnewtons/5807757 <!DOCTYPE> <html> <head> <meta http-equ…

資本冬天已至,開發者卻可以著眼未來

云&#xff0c;在國內外都已成為軟件開發者的首選服務。縱觀歷史&#xff0c;在云計算發展的這些年里&#xff0c;不管云上做了多少產品和服務&#xff0c;其實都離不開云最本質的價值體系&#xff1a;自服務、高彈性、按需提供、免運維&#xff0c;這些特性也讓云服務天然成為…

mybatis 大于_酸爽!IDEA 中這么玩 MyBatis,讓編碼速度飛起!

作者&#xff1a;Orsoncnblogs.com/java-class/p/6237564.html1. 搭建 MyBatis Generator 插件環境a. 添加插件依賴 pom.xmlb. 配置文件 generatorConfig.xmlc. 數據庫配置文件 jdbc.propertiesd. 配置插件啟動項2.項目實戰a. 比如在一個項目 我們要刪除某個小組下某個用戶的信…

Java的三種代理模式完整源碼分析

Java的三種代理模式&完整源碼分析 Java的三種代理模式&完整源碼分析 參考資料&#xff1a; 博客園-Java的三種代理模式 簡書-JDK動態代理-超詳細源碼分析 [博客園-WeakCache緩存的實現機制](https://www.cnblogs.com/liuyun1995/p/8144676.html) 靜態代理 靜態代理在使…

scatter函數_matplotlib.pyplot常用函數scatter講解大全(三)

前言這篇文章再來總結一個常用畫圖函數scatter-散點圖。參數常用參數示例import matplotlib.pyplot as plt import numpy as np#導入需要的包 datanp.random.multivariate_normal([0,1],[[1,0],[0,1]],200)#準備數據&#xff0c;二維正態分布plt.rcParams["axes.unicode_m…

如何徹底卸載MySQL

本文摘自&#xff1a;http://www.heiqu.com/show-64764-1.html 內容為&#xff1a; 由于安裝MySQL的時候&#xff0c;疏忽沒有選擇底層編碼方式&#xff0c;采用默認的ASCII的編碼格式&#xff0c;于是接二連三的中文轉換問題隨之而來&#xff0c;就想卸載了重新安裝MYSQL&…

vue-cli項目模板的一些思考

之前有個想法&#xff0c;就是要利用vue寫一套ui。然后當時也沒有搞清楚到底怎么寫。 幾經周轉吧&#xff0c;通過付費的方式在gitbook上面找到了答案。 找到答案之后再看我們正在開發的項目&#xff0c;看伙伴寫的代碼&#xff0c;突然發現完全可以按照寫ui組件庫的方式調整目…

flex基于svn協同開發

想做一個游戲&#xff0c;正好有人陪我做。于是想到用flex來協同開發。本來是想使用cvs&#xff0c;可是結果搗鼓了半天&#xff0c;也沒個結果——估計是最近沒怎么看電影&#xff0c;IQ降下來了。于是改用svn。 參考資料&#xff1a;http://www.flashmagazine.com/tutorials/…

cookie與session詳解

session與cookie是什么?session與cookie屬于一種會話控制技術.常用在身份識別&#xff0c;登錄驗證&#xff0c;數據傳輸等.舉個例子&#xff0c;就像我們去超市買東西結賬的時候&#xff0c;我們要拿出我們的會員卡才會獲取優惠.這時候&#xff0c;我們怎么識別這個會員卡真實…

c++萬能頭文件_初學Python,與C對比

?背景學了一學年的C的基礎&#xff0c;下學年開課Python&#xff0c;現在正在自學中...C也不是不學了&#xff0c;而是之前買了一本《CPrimer》在學校里&#xff0c;就準備先學一下Python&#xff0c;下學期利用自由時間接著學習C。這里分析了一下二者的優缺點&#xff0c;供大…

listen(int fd, int backlog)中的backlog含義

1. listen(int fd, int backlog)中的backlog不能限制連接數量??? http://bbs.chinaunix.net/viewthread.php?tid870564 backlog應該是未完成3次握手連接和已完成3次握手而未被accept的兩對列之和.不知道我說的對不? 如果要控制連接數量,是不是要自己編碼控制...下面的可以…

本地無法啟動MySQL服務,報的錯誤:1067,進程意外終止---解決

原文鏈接&#xff1a;http://blog.csdn.net/shenhonglei1234/article/details/5928873 在本地計算機無法啟動MYSQL服務錯誤1067進程意外終止 這種情況一般是my.ini文件配置出錯了 首先找到這個文件&#xff1a; 默認安裝路徑 C:/Program Files/MySQL/MySQL Server 5.1/my.ini …

一篇文章助你理解Python3中字符串編碼問題

前幾天給大家介紹了unicode編碼和utf-8編碼的理論知識&#xff0c;以及Python2中字符串編碼問題&#xff0c;沒來得及上車的小伙伴們可以戳這篇文章&#xff1a;淺談unicode編碼和utf-8編碼的關系和一篇文章助你理解Python2中字符串編碼問題。下面在Python3環境中進行代碼演示&…

Express框架開發知識點總結

express --viewpug myapp 以上語句在當前工作目錄中創建名為 myapp 的 Express 應用程序&#xff0c;采用的模板是jade。 以前還在糾結使用hbs模板引擎或者ejs模板&#xff0c;實際上只要將--view后面的pug換成hbs&#xff08;使用的是Handlebars模板引擎&#xff09;&#xff…