废话没有,直奔主题
问题点:
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更多配置项,大家可以看过的上一篇文章
当然很多参数我也不知道怎么用,如果大家找到其用途,麻烦留言告知,不胜感激,传送门