如何在多图上传插件中实现超1MB图片时禁用提交按钮?
问题
我是JavaScript新手,正在使用一款多图上传插件。我的需求是:当上传的任意图片大小超过1MB时,禁用id为btnSubmit的提交按钮。请问代码$('#btnSubmit').prop('disabled', true);应该放置在哪个位置?
插件界面预览

HTML视图
<div class="multiple-uploader" id="multiple-uploader"> <div class="mup-msg"> <span class="mup-main-msg">click to upload images.</span> <span class="mup-msg" id="max-upload-number">Upload up to 10 images</span> <span class="mup-msg">Only images, pdf and psd files are allowed for upload</span> </div> </div> <button type="submit" id="btnSubmit" class="btn btn-primary w-100">Save</button>
插件JavaScript代码
class MultipleUploader { #multipleUploader; #$imagesUploadInput; constructor( multiUploaderSelector ) { this.#multipleUploader = document.querySelector(multiUploaderSelector); this.#$imagesUploadInput = document.createElement('input') } init( { maxUpload = 3 , maxSize = 1 , formSelector = 'form' , filesInpName = 'images' } = {} ) { const form = document.querySelector(formSelector); if (! this.#multipleUploader ) // check if the end user didnt write the multiple uploader div throw new Error('The multiple uploader element doesnt exist'); if (! form ) // check if there is no form with this selector throw new Error('We couldn\'t find a form with this selector: ' + formSelector); // ensure that the form has enctype attribute with the value multipart/form-data form.enctype = 'multipart/form-data' if ( document.getElementById('max-upload-number') ) document.getElementById('max-upload-number').innerHTML = `Upload up to ${ maxUpload } files`; // create multiple file input and make it hidden this.#$imagesUploadInput.type = 'file'; this.#$imagesUploadInput.name = `${filesInpName}[]`; this.#$imagesUploadInput.multiple = true; this.#$imagesUploadInput.accept = "image"; this.#$imagesUploadInput.class = "image"; this.#$imagesUploadInput.style.setProperty('display','none','important'); // create multiple file input and make it hidden // append the newly created input to the form with the help of the formSelector provided by the user document.querySelector(formSelector).append( this.#$imagesUploadInput ); this.#multipleUploader.addEventListener("click", (e) => { if ( e.target.className === 'multiple-uploader' || e.target.className === 'mup-msg' || e.target.className === 'mup-main-msg' ) this.#$imagesUploadInput.click() // trigger the input file to upload images }); const self = this; // preview the uploaded images this.#$imagesUploadInput.addEventListener("change",function () { if (this.files.length > 0) { self.#multipleUploader.querySelectorAll('.image-container').forEach( image => image.remove() ); // clear the previous rendered images self.#multipleUploader.querySelector('.mup-msg').style.setProperty('display', 'none'); // hide the hint texts inside drop zone // if the length of uploaded images greater than the images uploaded by the user, the maximum uploaded will be considered const uploadedImagesCount = this.files.length > maxUpload ? maxUpload : this.files.length; const unAcceptableImagesIndices = []; for (let index = 0; index < uploadedImagesCount; index++) { const imageSize = self.#bytesToSize( this.files[ index ].size ); const isImageSizeAcceptable = self.#checkImageSize( index , imageSize , maxSize , 'MB' ); // appended the newly created image to the multiple uploader self.#multipleUploader.innerHTML += ` <div class="image-container" data-image-index="${ index }" id="mup-image-${ index }" data-acceptable-image="${ +isImageSizeAcceptable }" > <div class="image-size"> ${ imageSize['size'] + ' ' + imageSize['unit'] } </div> ${ !isImageSizeAcceptable ? `<div class="exceeded-size"> greater than ${ maxSize } MB </div>` : '' } <img src="${ URL.createObjectURL( this.files[ index ]) }" class="image-preview" alt="" /> </div>`; if ( ! isImageSizeAcceptable ) unAcceptableImagesIndices.push( index ) } unAcceptableImagesIndices.forEach( (index ) => self.#removeFileFromInput(index, false )) } }); // event for deleting uploaded images document.addEventListener('click',function(e){ if( e.target.className === 'image-container' ) // clicked on remove pseudo element { const imageIndex = e.target.getAttribute(`data-image-index`) const imageIsAcceptable = e.target.getAttribute(`data-acceptable-image`) e.target.remove() // remove the html element from the dom if ( +imageIsAcceptable ) self.#removeFileFromInput(imageIndex) if ( document.querySelectorAll('.image-container').length === 0 ) // if there are no images self.clear(); self.#reorderFilesIndices(); // reorder images indices } }); return this; } clear() { this.#multipleUploader.querySelectorAll('.image-container').forEach( image => image.remove() ); this.#multipleUploader.querySelectorAll('.mup-msg').forEach( msg => msg.style.setProperty('display', 'flex') ); this.#$imagesUploadInput.value = []; } #removeFileFromInput( deletedIndex ) { // remove the delete file from input const dt = new DataTransfer() for (const [ index, file] of Object.entries( this.#$imagesUploadInput.files )) { if ( index != deletedIndex ) dt.items.add( file ) } this.#$imagesUploadInput.files = dt.files // remove the delete file from input } #reorderFilesIndices() { document.querySelectorAll('.image-container').forEach( ( element, index) => { element.setAttribute('data-image-index', index.toString() ); element.setAttribute('id',`mup-image-${ index }`) }); } #checkImageSize( imageIndex, imageSize , maxSize ) { return imageSize['unit'] !== 'MB' || ( imageSize['unit'] === 'MB' && ( imageSize['size'] <= maxSize ) ) ; // return true if acceptable } #bytesToSize(bytes) { const sizes = ['Bytes', 'KB', 'MB'] const i = parseInt( Math.floor(Math.log(bytes) / Math.log(1024) ), 10) if (i === 0) return {size: bytes , unit: sizes[i] } else return {size: (bytes / (1024 ** i)).toFixed(1) , unit: sizes[i] } } }
解决方案
你需要在两个核心位置添加按钮状态控制逻辑,既要处理上传时的违规检查,也要处理删除图片后的状态更新:
1. 上传图片时的状态设置
在#$imagesUploadInput的change事件处理函数中,遍历完所有图片并处理完违规图片后,添加按钮状态判断:
找到这段代码:
unAcceptableImagesIndices.forEach( (index ) => self.#removeFileFromInput(index, false ))
在它之后添加:
// 检查是否存在违规图片,设置按钮禁用状态 const hasInvalidImages = unAcceptableImagesIndices.length > 0; $('#btnSubmit').prop('disabled', hasInvalidImages);
这段代码要放在change事件的if(this.files.length>0)代码块的末尾位置。
2. 删除图片后的状态更新
当用户删除图片后,需要重新检查剩余所有图片的合规性,更新按钮状态:
找到删除图片的click事件处理函数,在self.#reorderFilesIndices();之后添加:
// 删除图片后重新检查所有剩余图片是否合规 let allImagesValid = true; document.querySelectorAll('.image-container').forEach(container => { if (container.getAttribute('data-acceptable-image') === '0') { allImagesValid = false; } }); $('#btnSubmit').prop('disabled', !allImagesValid);
额外提示
- 如果你没有引入jQuery,可改用原生JS语法:
document.getElementById('btnSubmit').disabled = hasInvalidImages; - 建议页面初始加载时,将按钮设置为禁用状态,直到用户上传了合规的图片;或者如果有默认已上传的图片,初始化时也要做一次合规检查。
内容的提问来源于stack exchange,提问作者Malik Zubair Mukhtar
相关产品推荐
相关产品推荐

