廢話沒有,直奔主題
問題點:
fileinput提供了一個maxFileCount用於限制圖片上傳的數量,設置maxFileCount為1時,一次性選擇超過一張會有如下提示:

當選擇一張,不點上傳,再次選擇一張時,會這樣提示:

但坑爹的是,當選擇一張圖片后點上傳,然后再選擇一張再次點上傳就可以完美的繞過這個限制,此時maxFileCount就失去了應有的效果
解決方案:
解決思路很簡單,當用戶選擇文件數超過指定數量時直接禁用選擇按鈕,就是給選擇按鈕加個disabled屬性。
fileinput提供了一系列事件鈎子,可以用來解決這個問題,之所以寫這篇文章,就是因為這些事件鈎子在網上都找不全,導致不少人想出各種歪招來解決,下面是廢話,不想看就直接看代碼
為了解決這個問題,本人曾經翻遍源碼,把所有的事件鈎子和配置項都整理了出來,限於時間關系沒有深究具體用法,只在碰到問題時再去研究,以問題為導向能大大提高效率
廢話不多說,上代碼
$("#imgUpload").fileinput({
language: 'zh', //設置語言,
uploadUrl: "/upload/uploadimg/",
showCaption: false,
browseClass: "btn blue",
removeClass: "btn red",
allowedFileExtensions: ['jpg', 'png', 'gif'],
overwriteInitial: false,
maxFileSize: 70000,
maxFileCount: 0, // 這里設為0,由於存在bug,這個屬性相當於沒什么用了,判斷是否超限統一用事件鈎子來執行
uploadClass: "btn green",
removeClass: "btn red",
uploadAsync: true,
browseLabel: '選擇',
dropZoneEnabled: false,
previewSettings: {
image: {width: "auto", height: "100px"}
},
layoutTemplates: {
actionUpload: ""
},
/* minImageWidth: 1205,
minImageHeight: 405,
maxImageWidth: 1205,
maxImageHeight: 405,*/
// maxFileSize: 100,
msgFilesTooMany: "選擇上傳的文件數量({n}) 超過允許的最大數值{m}!",
uploadExtraData: {
prefix: 'gg_img'
},
initialPreview: {$info.imgs|default='[]'},
initialPreviewAsData: true,
initialPreviewFileType: 'image',
initialPreviewConfig: {$info.previewconfig|default='[]'},
})
.on('filebatchselected', function (evt, file) {
// 選擇圖片后執行,用於判斷選擇的圖片是否超出限制,超出限制就禁用選擇按鈕
// 比如只允許上傳4張,我分兩次上傳,第一次上傳兩張,第二次上傳3張,此時手動禁用選擇按鈕
if($uploadAdvBox.find('.file-preview-frame').length > $uploadLimit.val()) {
$('#imgUpload').attr('disabled', 'disabled')
$('#imgUpload').closest('div.btn-file').addClass('btn-disabled');
}
})
.on('filebatchuploadcomplete', function (evt, file) {
// 只會調用一次,所有圖片都上傳成功調用,這是為了彌補上傳成功后部分DOM結構重新渲染,導致filebatchselected鈎子中執行的操作失效
if($uploadAdvBox.find('.file-preview-frame').length > $uploadLimit.val()) {
$('#imgUpload').attr('disabled', 'disabled')
$('#imgUpload').closest('div.btn-file').addClass('btn-disabled');
}
})
.on('fileuploaded', function (event, data, previewId, index) {
// 上傳成功幾次就調用幾次,把后端返回的地址附加到DOM結構上,為以后得操作做准備
if (data.response.status == 1) {
$uploadAdvBox.find('#'+previewId).attr('data-url', data.response.data.name);
} else {
alert(data.response.info);
}
})
.on('fileclear', function (evt, file) {
// 點擊右上角叉叉執行
$('#imgUpload').removeAttr('disabled')
$('#imgUpload').closest('div.btn-file').removeClass('btn-disabled')
$uploadAdvBox.find('.fileinput-upload-button').removeAttr('disabled')
})
.on("filesuccessremove",function(event, uploadedId, index){
// 僅對上傳成功的圖片有效,未上傳的圖片不執行這里
// 延遲一秒后刪除,否則不准確
setTimeout(function () {
if($uploadAdvBox.find('.file-preview-frame').length < $uploadLimit.val()) {
$('#imgUpload').removeAttr('disabled')
$('#imgUpload').closest('div.btn-file').removeClass('btn-disabled')
}
}, 1000)
})
.on('fileremoved', function () {
// 該事件鈎子針對只選擇不上傳的情況
if($uploadAdvBox.find('.file-preview-frame').length <= $uploadLimit.val()) {
$('#imgUpload').removeAttr('disabled')
$('#imgUpload').closest('div.btn-file').removeClass('btn-disabled')
$uploadAdvBox.find('.fileinput-upload-button').removeAttr('disabled')
}
})
這里要特別注意的是,這些事件鈎子有執行時間線,這個時間線也是本次研究出來的,已經作為注釋寫上了
下面是DOM結構,js代碼中存在一些變量,大家對照着DOM結構一眼就能明白是什么意思了
<div id="upload_adv_box">
<input id="imgUpload" type="file" multiple name="img_upload" value="上傳"/>
</div>
最后
個人的力量是有限的,關於fileinput更多配置項,大家可以看過的上一篇文章
當然很多參數我也不知道怎么用,如果大家找到其用途,麻煩留言告知,不勝感激,傳送門
