jQuery拖拽上传:如何将拖拽文件同步至input控件?
拖拽上传无法同步文件到input控件的解决方法
我需要实现拖拽上传与点击浏览结合的功能,点击浏览能正常把文件放进input控件,但拖拽只能通过dataTransfer获取文件详情、更新拖拽区域文件名,没法把文件同步到input控件里。
我试过这段代码:
$('#ModalDropZone').on('drop', function () { event.stopPropagation(); event.preventDefault(); const vInput = $('#DocFileUpload') alert("DropZone changed") var vFile = event.dataTransfer.files; var vName = event.dataTransfer.files[0].name; var vLength = vFile.length; if (vLength > 0) { alert(vName); // vInput.files = event.originalEvent.dataTransfer.files; vInput.files = event.dataTransfer.files; $('#ModalDropZone').html(vName); $('#DocFileUpload').files(vFile); } });
更新:试了各种给input加文件的方法,要么没反应要么报错。调试时能看到文件,但后续拿文件句柄(用来上传)的时候,文件长度一直是0。
解决方法
input的files属性是只读的,不能直接赋值,而且jQuery对象不能直接操作原生DOM的属性,以下是可行的实现方案:
- 修正事件对象与DOM元素获取
jQuery封装的事件里,dataTransfer藏在originalEvent属性中,同时要把jQuery对象转成原生DOM元素才能操作files:
$('#ModalDropZone').on('drop', function (event) { event.stopPropagation(); event.preventDefault(); // 转成原生input元素 const inputEl = $('#DocFileUpload')[0]; // 从原生事件对象里取文件列表 const files = event.originalEvent.dataTransfer.files; if (files.length > 0) { // 构造可赋值的FileList const dataTransfer = new DataTransfer(); // 把拖拽的文件添加到DataTransfer Array.from(files).forEach(file => dataTransfer.items.add(file)); // 给input的files属性赋值 inputEl.files = dataTransfer.files; // 更新拖拽区域显示文件名 $('#ModalDropZone').html(files[0].name); } });
- 补充dragover事件处理
必须阻止dragover的默认行为,否则浏览器会直接打开拖拽的文件,不会触发drop事件:
$('#ModalDropZone').on('dragover', function (event) { event.stopPropagation(); event.preventDefault(); // 可选:添加拖拽时的样式,比如给区域加边框高亮 $(this).css('border-color', '#2196F3'); }); // 可选:拖拽离开时恢复样式 $('#ModalDropZone').on('dragleave', function () { $(this).css('border-color', '#ccc'); });
- 上传逻辑兼容
不管是点击浏览还是拖拽上传,现在input里都有正确的文件列表,上传时直接从input取即可:
function handleUpload() { const inputEl = $('#DocFileUpload')[0]; const formData = new FormData(); // 把所有文件加入FormData Array.from(inputEl.files).forEach(file => { formData.append('uploadFiles', file); }); // 用jQuery发送上传请求 $.ajax({ url: '/your-upload-api', type: 'POST', data: formData, // 必须设置这两个属性,否则FormData会被错误解析 processData: false, contentType: false, success: (res) => { console.log('上传完成', res); }, error: (err) => { console.error('上传失败', err); } }); }
核心要点
- 不要直接给jQuery对象的
files赋值,必须操作原生DOM元素 - input的
files是只读属性,只能通过DataTransfer构造新的FileList来赋值 - 必须阻止
dragover和drop的默认行为,否则拖拽事件无法正常触发
内容的提问来源于stack exchange,提问作者gchq
相关产品推荐
相关产品推荐

