日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

定制jQuery File Upload为微博式单文件上传

發布時間:2023/12/9 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 定制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的最簡模型

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工作流程:

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

    總結

    以上是生活随笔為你收集整理的定制jQuery File Upload为微博式单文件上传的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。