头像、附件、后台传图都会用到:点一下弹出选文件,也能把文件直接拖进框里。这版用 jQuery 1.9.1。核心是浏览器自带的拖放和 File。
嵌入项目时,按后面「接入后端接口」那节补上传请求就行。
使用的文件有哪些

jQuery 必须写在 index.js 前面,不然 $ 还没定义。index.js 包在 $(function () {}) 里,放 <head> 也会等 DOM 好了再绑。

业务就这几个名字,后面会反复碰到:
1、.box:可点、可拖的那块区域
2、#fileIpt:隐藏的 file 框,点 .box 时帮你弹出系统选文件
3、#preview:预览图
4、imgUrl:createObjectURL 给的临时地址
5、showPreview(file):点选和拖放最后都进这里
实现了那些功能
点击和拖放走同一条预览
两条路最后都把文件交给 showPreview。点框 → 触发隐藏的 #fileIpt → change 里取出 files[0];拖进来 → drop 里取 e.originalEvent.dataTransfer.files[0]。后面预览、上传都只对接这一个函数,别在点击和拖放里各写一遍。
拖上去要高亮,拖走了得消掉
我第一次看也卡了一下。说白了:框上没有可靠的「拖出去」事件,dragleave 动不动就误触发。所以在整页的 dragenter 上判断:目标还在 .box 里就加 hover,否则拿掉。拖到框上边框变蓝、底变成天蓝色;拖到页面空白处高亮就没了。
还有一件事必须做:dragover 和 drop 都要 preventDefault。浏览器默认会把拖进来的文件直接打开,你不拦,预览逻辑根本跑不到。这坑我见过不止一次。
本地预览别忘了释放地址
URL.createObjectURL(file) 会给这个文件一个临时地址,拿来当 #preview 的 src 就能立刻看到图,不用先传到服务器。这个地址要存到 imgUrl 里。换一张图之前先 URL.revokeObjectURL(imgUrl),不然旧地址一直占着内存,狂换图会越用越卡。
选文件框用页面里那个隐藏的 #fileIpt,选完把 value 清空,同一张图再选一次也能触发 change。
如何嵌入到项目中
接入项目时:预览还是 showPreview,真正上传用 FormData 走 ajax。jQuery 这套建议用 Layui 的 layer.msg 做提示,不要 alert,具体按实际项目来定。点框和拖放拿到文件之后,先校验再调后端,成功了再预览。showPreview 不用改,只是成功后再调用它。
需要修改的参数
1、类型:本例点选用 accept="image/*";拖放不会走这个限制,drop 里还得自己看 file.type。
2、大小:按业务定,常见是 2MB、5MB,超了提示、不要传。
3、多文件:dataTransfer.files 和 input.files 都是列表,本例只取第一张图省事;要多张就遍历,别写死 [0]。
接入后端接口的完整示例
页面结构还是拖放区 + 隐藏 file + 预览图,样式用原来的 index.css。接口地址和 res.code 换成项目里的约定。

processData、contentType 都得是 false,不然 jQuery 会把 FormData 拆成字符串,文件就传不上去。
总结
1、点击和拖放最后都进同一个函数,预览用 createObjectURL,换图前先 revokeObjectURL。
2、整页听 dragenter 来加减高亮;dragover / drop 一定要 preventDefault,否则浏览器会直接打开文件。
3、嵌入项目时:校验类型和大小,再用 FormData 调后端。jQuery 这套建议用 Layui 做提示,具体按实际项目来定。