好幾天沒有寫文章了,最近在做公司的一個後臺圖片上傳,基於Huploadify重寫了一下這個外掛,在它的基礎上做了一些定製,已經託管在github,可以通過這裡獲悉。
簡介
有一個著名的圖片上傳外掛uploadify,在這個外掛基礎上,Huploadify被開發出來,是由國人開發的,使用起來也比較好用。但是,我 希望對自己的專案進行定製,希望實現像淘寶新增圖片那樣,點選一個上傳按鈕,然後自己上傳,上傳的時候,有一個進度條,上傳完之後,預覽圖片。
同時,在Huploadify基礎上,還增加了單個圖片上傳,比如在上傳頭像的時候,不可能讓你上傳多張圖片。
因此,我在Huploadify的基礎上進行修改,得到了HHuploadify。
HHuploadify的用法和Huploadify的用法是一模一樣的。不過增加了幾個點:
-
增加isSingle配置項,在初始化的時候,如果isSingle=true,那麼這個上傳只能上傳一張圖片。domo.html中有案例
-
增加了上傳圖片結束後,將圖片顯示到該上傳區域中預覽,返回格式必須是json,有一個url欄位。upload.php中有案例
修改樣式:通過修改HHuploadify.css檔案中的樣式來控制表現。
上傳後得到的圖片預覽是通過將圖片作為該區域的背景圖片實現的,因此,如果要調整該圖片,必須通過css來進行控制。
安裝
獲取程式碼:從我的github上下載HHuploadify的原始碼。
首先,你的網頁中得引入jquery
<script src="jquery-2.2.0.min.js"></script>
其次,再網頁中引入外掛檔案
<script src="jquery.HHuploadify.js"></script>
再次,再網頁頭部引入HHuploadify的樣式檔案
<link rel="stylesheet" href="HHuploadify.css">
如果你想對HHuploadify的樣式進行修改,可以修改HHuploadify.css檔案中的具體規則,改完之後,把上面的地址改為HHuploadify.css,從而使用新的樣式。當然,你也可以把裡面的樣式全部拷貝出來,放到自己的樣式檔案裡面去,這樣就可以不用引用HHuploadify.css。
使用
HHuploadify會初始化一個按鈕,讓你進行上傳。因此,在你需要展示這個按鈕的地方做如下操作。假如你想呼叫的容器為<div id=”upload”></div>,只需要在網頁底部加入如下程式碼:
<script>
$(`#upload`).HHuploadify({
fileTypeExts:`*.jpg;*.png;*.gift`,
uploader:`upload.php` // 必須的,必須指定用來處理上傳邏輯的後端處理URL
});
</script>
這樣,就可以初始化一個按鈕,點選按鈕之後可以多選多張圖片,每張圖片會各自提交到upload.php。這裡提示一下,uploadify本身就是一張一張圖片提交的,而不是所有圖片一起提交。upload.php可以是你自己的URL,在這個URL進行圖片處理和儲存,並且返回一個包含url欄位的json字串,通過這個url欄位讓上傳區域展示圖片。
單張片上傳
你可能現在想上傳一張頭像圖片,先把css改為你想要的結果。在上面的程式碼中,只需要加入一個isSingle引數即可:
<script>
$(`#upload`).HHuploadify({
fileTypeExts:`*.jpg;*.png;*.gift`,
isSingle:true,
uploader:`upload.php`
});
</script>
這樣,這個區域只能進行一張圖片的上傳。
初始化引數
fileTypeExts:`.`,//允許上傳的檔案型別,格式`.jpg;.doc` uploader:“,//檔案提交的地址
auto:true,//是否開啟自動上傳 method:`post`,//傳送請求的方式,get或post
multi:true,//是否允許選擇多個檔案 isSingle:false,//
是否是單個檔案上傳,如果是單個檔案上傳,選擇檔案後,上傳按鈕會消失,multi也會被強制設定為false
formData:null,//傳送給服務端的引數,格式:{key1:value1,key2:value2}
fileObjName:`file`,//在後端接受檔案的引數名稱,如PHP中的$_FILES[`file`]
fileSizeLimit:2048,//允許上傳的檔案大小,單位KB
showUploadedFilename:false,//是否顯示上傳檔名
showUploadedPercent:false,//是否實時顯示上傳的百分比,如20%
showUploadedSize:false,//是否實時顯示已上傳的檔案大小,如1M/2M
buttonText:`選擇檔案`,//上傳按鈕上的文字 removeTimeout: 1000,//上傳完成後進度條的消失時間,單位毫秒
itemTemplate:itemTemp,//上傳佇列顯示的模板 onUploadStart:null,//上傳開始時的動作
onUploadSuccess:null,//上傳成功的動作 onUploadComplete:null,//上傳完成的動作
onUploadError:null, //上傳失敗的動作 onInit:null,//初始化時的動作
onCancel:null,//刪除掉某個檔案後的回撥函式,可傳入引數file
onClearQueue:null,//清空上傳佇列後的回撥函式,在呼叫cancel並傳入引數*時觸發
onDestroy:null,//在呼叫destroy方法時觸發 onSelect:null,//選擇檔案後的回撥函式,可傳入引數file
onQueueComplete:null//佇列中的所有檔案上傳完成後觸發
以上是HHuploadify的所有預設初始化引數,除了isSingle以外,其他所有的都是和Huploadify一樣的,只不過我修改了它的預設值。
具體文件請閱讀Huploadify。
例子
上傳圖片後提交儲存相簿
現在模擬用HHuploadify來做一個相簿。使用者先建立了一個相簿A,多選圖片,上傳到該相簿,圖片全部由資料庫儲存URL,並有對應的ID,現在要求,有一個相簿和圖片的關係資料表album_photo_relation用來儲存哪一張圖片屬於哪一個相簿。那麼問題來了,如何在上傳圖片的時候實現這個過程呢?
很簡單,在初始化引數中增加formData引數,比如:
<script>
$(`#upload`).HHuploadify({
fileTypeExts:`*.jpg;*.png;*.gift`,
formData: {album_id: <?=$album_id?>},
uploader:`upload.php`
});
</script>
在upload.php中就能接收到該相簿的ID:$_POST[`album_id`]。這樣,在upload.php中就可以在插入完photo獲得photo_id後,再向alubm_photo_relation表中插入一條記錄。
現在問題又來了,加入要求不允許先建立相簿、進入相簿再上傳,現在要求相簿建立時先上傳圖片,上傳完之後,和相簿資訊(如名稱、描述等)一同提交到create_album.php。
這就複雜了,因為不能通過formData,直接在upload.php中完成每一張圖片的操作。怎麼辦呢?我的解決辦法是,在圖片上傳完成後,將圖片的photo_id載入到當前的頁面裡面,提交建立相簿的時候,同時可以知道該相簿有哪些圖片。
<script>
$(`#upload`).HHuploadify({
fileTypeExts:`*.jpg;*.png;*.gift`,
uploader: `upload.php`,
onUploadSuccess: function(file,data) {
var photo = JSON.parse(data);
var photo_id = photo.id;
var instanceNumber = $(`.uploadify`).length+1;
var file_index = file.index;
$(`#fileupload_` + instanceNumber + `_` + file_index).append(`<input type="hidden" name="photo_id[]" value="` + photo_id + `">`);
}
});
</script>
上面的程式碼主要利用到了onUploadSuccess事件,及當一張圖片上傳成功之後的回撥。這樣,在刪除的時候,可以刪除掉對應的input,在提交的時候,可以提交對應的photo_id[]。
上傳完圖片後可對圖片進行拖動排序
在相簿的案例中,有一種情況是,還可以對圖片進行拖動,調整圖片組的順序。怎麼實現呢?首先你得有一個能夠實現拖動的jquery外掛,我推薦DragSort。
<script src="jquery.dragsort-5.2.0.min.js"></script>
<script>
$(`#upload`).HHuploadify({
fileTypeExts:`*.jpg;*.png;*.gift`,
uploader:`upload.php`,
onQueueComplete:function() {
var instanceNumber = $(`.uploadify`).length+1;
var $instance = $(`#file_upload_` + instanceNumber + `-queue`);
$instance.dragsort("destroy");
$instance.dragsort({
dragSelector: "div.uploadify-queue-item",
dragBetween: true,
dragEnd: function(){
$instance.find(`.uploadify-queue-item`).removeAttr(`style`);
},
placeHolderTemplate: `<div class="uploadify-queue-item"></div>`
});
}
});
</script>
上面的程式碼通過一個onQueueComplate事件繫結,在所有檔案上傳結束後,執行函式中的動作。函式中的動作可以使該區域內的所有圖片區域繫結dragsort,實現拖動排序的功效。
擴充套件函式
為了實現更簡潔的載入,我新增了HHuploadifyReady.js,裡面有兩個函式initHHuploadify函式和resetHHuploadify函式。
function initHHuploadify(selector,uploader,field,isSingle)
selector是要初始化的選擇器,uploader是上傳後端處理URL,field是回撥的時候,往區域內插入的input的name值,注意,插入的input name=field[],提交的是一個陣列,後端應該注意一下。isSingle就不解釋了,表示是否單個圖片上傳,當為true時,input name=field,不是陣列。
為了便於使用,一般再使用的時候,你可以不設定第四個引數,而是使用下面這個函式:
function initHHuploadifyOne(selector,uploader,field)
這個函式是從上面的函式衍生出來的,不用傳第四個引數,即可讓HHuploadify初始化為一個只能上傳一張圖片的區域。
function resetHHuploadify(selector,images,field)
當完成初始化之後,你會發現,有的時候你的頁面上需要放置幾張圖片進去,比如在編輯相簿的時候,你的相簿中本身已經存在了一些圖片了,所以你在編輯它的時候,必須讓相簿中的圖片都顯示出來,這個時候,需要用resetHHuploadify來實現。它有三個引數,selector和前面的一樣,都是指初始化時的物件選擇器,例如$(selector)在前面的案例中就是$(`#upload`)。images是一個物件陣列,包含了要用於顯示的圖片資訊,首先它是一個陣列,其次它的每一個元素又是物件,形式如下:
[{`id` => 4,`url` => `/images/afa.jpg`},{`id` => 56,`url` =>
`/images/aafdsfa.jpg`},{`id` => 12,`url` => `/images/12fa.jpg`}]
為什麼要這樣呢?id是用來作為input的value值的,url是用來展示圖片的,就是這樣。field則是input的name值,注意,由於是多個input,所以它也是input name=field[],是個陣列,後端接收的時候要注意。
不過在resetHHuploadify的基礎上,也衍生出了resetHHuploadifyOne
function resetHHuploadifyOne(selector,image,field)
唯一的區別在於第二個引數,由images變為image,不是一個陣列,而是一個物件,形式如下:
{`id` => 56,`url` => `/images/aafdsfa.jpg`}
只有一張圖片的資訊。
OK,對HHuploadify的推介就到這裡了,如果你有不懂的地方,歡迎到我的github去提交issue。