必须先引入 Jquery 依赖

1.文件结构

2. HTML

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>拖拽</title>
<link rel="stylesheet" type="text/css" href="./css/index.css" />
<script src="./js/jquery-3.5.1.min.js"></script>
<script src="./js/index.js"></script>
</head>
<body>
<!-- 触发按钮 -->
<button type="button" id="clickBtn" class="clickBtn">点击选择</button>
<!-- 拖拽盒子 -->
<div id="select_file_div"class="select_file_div">
<div id="drag_file_div"class="drag_file_div"contenteditable="true">
<p class="drag_file_div_p"contenteditable="false">请选择或拖拽文件至此区域</p>
</div>
<div id="drag_file_control"class="drag_file_control noSelect">
<p>暂未选择文件</p><span>按住任意拖动</span>
<div id="drag_file_cancel"class="drag_file_cancel">完成</div><a
href="javascript:void(0);"id="select_file_a"class="select_file_a"><input
type="file"multiple="true"id="select_file_addFile"class="select_file_addFile">手动选择</a>
</div>
</div>
</body>
</html>

3. CSS

*{margin:0;padding:0;box-sizing:border-box}.clickBtn{width:148px;height:48px;letter-spacing:4px;font-size:16px;margin:16px 0 0 16px}.tip{width:auto;min-width:168px;height:60px;position:fixed;left:44%;z-index:199;padding:0 8px 0 8px;line-height:60px;text-align:center;font-size:18px;border-radius:4px;box-shadow:#393D49 2px 2px 8px;background-color:#1E9FFF;color:#ffffff;animation:tip 0.3s;animation-fill-mode:forwards;-webkit-animation-fill-mode:forwards}@keyframes tip{from{top:0px}to{top:80px}}@-webkit-keyframes tip{from{top:0px}to{top:80px}}.tipKill{animation:tipKill 1s;animation-fill-mode:forwards;-webkit-animation-fill-mode:forwards}@keyframes tipKill{from{top:80px}to{background-color:rgba(0,0,0,0);box-shadow:rgba(0,0,0,0) 2px 2px 8px;color:rgba(0,0,0,0);top:0px}}@-webkit-keyframes tipKill{from{top:80px}to{background-color:rgba(0,0,0,0);box-shadow:rgba(0,0,0,0) 2px 2px 8px;color:rgba(0,0,0,0);top:0px}}.noSelect{-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.select_file_div{display:none;width:650px;position:fixed;top:20%;left:32%;z-index:101}.drag_file_div{width:100%;height:340px;padding:3px;background:url("../img/b2.jpg");background-size:100%;border:1px solid #4b4b4b;box-shadow:inset 0 1px 1px #d6d6d6;outline:medium;font-size:14px}.drag_file_div>p{position:absolute;width:240px;height:50px;text-align:center;left:0;top:0;right:0;bottom:0;margin:auto;border:1px dashed #ddd;font-size:1em;color:#999;display:block;line-height:50px}.drag_file_selectfile{width:98%;height:38px;margin:8px 1%;line-height:38px;color:#bfbfbf;background-color:#393D49;box-shadow:1px 1px 1px #ffffff}.drag_file_selectfile:hover{color:#eeeeee;box-shadow:2px 2px 4px #ffffff}.drag_file_selectfile>div{float:left}.drag_file_selectfile .select_filename{width:388px;height:38px;margin-left:10px}.drag_file_selectfile .select_filesize{width:168px;margin-left:10px}.drag_file_selectfile .select_file_clear{display:block;width:20px;height:20px;margin:9px;background:url("../img/delete1.png");background-size:100%;cursor:pointer}.drag_file_selectfile .select_file_clear:hover{background:url("../img/delete2.png");background-size:100%}.drag_file_selectfile>div>span:nth-child(1){font-weight:700;margin:0 6px 0 0}.drag_file_control{width:650px;margin:0 auto;height:45px;line-height:45px;background:#393D49;border-width:0 1px 1px 1px;border-style:solid;border-color:#747474;cursor:pointer}.drag_file_control .select_file_a{position:relative;width:92px;height:34px;line-height:34px;text-decoration:none;color:#ffffff;font-size:14px;letter-spacing:2px;cursor:pointer;background:#89a3b3;border-radius:3px;overflow:hidden;text-align:center;float:right;margin:5px 8px 5px}.drag_file_control .select_file_a>input{position:absolute;width:92px;height:34px;right:0;top:0;opacity:0;cursor:pointer}.select_file_addFile{display:block;margin:0 auto;text-align:center;font-size:14px;cursor:pointer}.drag_file_control>p{width:158px;color:#d9d9d9;float:left;font-size:14px;padding-left:20px}.drag_file_control>span{margin:0 0 0 24px;color:#666;font-size:14px}.dragOver{box-shadow:inset 1px 1px 2px rgba(0,0,0,.5) !important}.drag_file_cancel{width:92px;height:34px;background:#1c8fe5;color:#eeeeee;font-size:14px;letter-spacing:4px;border-radius:3px;display:block;line-height:34px;text-align:center;cursor:pointer;float:right;margin:5px 8px 5px}.select_file_a:hover,.drag_file_cancel:hover{opacity:0.6}

4. JS

var selectFileArr = new FormData(); // 选中文件
var selectFileArrKey = []; // 选中文件名集合
var selectFileSizeSum = 0; // 选中文件总大小
var maxFileNum = 1; // 选择文件数量上限
var maxFileSize = 100; // 选择文件大小上限(单位Mb)
var sheetErrorData = {}; // 导入失败数据
var canFileType = ['.xlsx']; // 允许的文件类型
var dragFileDiv = null; // 显示对象_主体盒子
var dragFileTip = null; // 显示对象_提示内容 var errTip = {'background-color': '#ff6528', 'color': '#eeeeee', 'font-weight': '700'}; $(function() {
// 拖拽移动
dragMove('#select_file_div', false); // 点击选择文件
$('#clickBtn').click(function() {
var parameter = {
maxFileNum: 7,
maxFileSize: 100
}
dragSelectFileLoad(parameter); // 加载
});
}); /**
* 加载函数
* @param parameter JSON参数对象
*/
function dragSelectFileLoad(parameter) {
$('body')[0].contentEditable = false; // 规定元素内容是否可编辑
$('#select_file_div').show(); // 显示盒子
maxFileNum = parameter.maxFileNum || 1; // 最多可选取文件数
maxFileSize = parameter.maxFileSize || 1; // 选择文件大小上限(单位Mb)
// 显示对象
dragFileDiv = $('#drag_file_div')[0];
dragFileTip = $('.drag_file_div_p');
// 鼠标拖入时
dragFileDiv.ondragenter = function(ev) {
dragFile.evStop(ev);
dragFileTip.text('请释放鼠标');
$(this).addClass('dragOver');
}
// 移出
dragFileDiv.ondragleave = function(ev) {
dragFile.evStop(ev);
dragFileTip.text('请添加或拖拽文件至此区域');
$(this).removeClass('dragOver');
}
// 释放元素
dragFileDiv.ondrop = function(ev) {
dragFile.evStop(ev);
this.setAttribute('contenteditable', 'false'); // 不可再拖动
dragFile.readFile(ev);
}
// 选择文件后
$('#select_file_addFile').change(function() {
dragFile.addCheck($('#select_file_addFile')[0].files[0]); // 文件校验
});
// 取消按钮
$('#drag_file_cancel').click(function() {
$('#select_file_div').hide();
});
} /**
* 拖拽文件操作对象
*/
var dragFile = {
// 读取拖拽文件
readFile: function(ev) {
var File = ev.dataTransfer.files;
for (var i = 0; i < File.length; i++) {
dragFile.addCheck(File[i]);
}
},
// 文件格式验证
addCheck: function(file) {
var fnLast = file.name.substr(file.name.lastIndexOf('.'));
if (!isNull(file.name) && canFileType.indexOf(fnLast) != -1) { // 文件类型校验
// console.log(selectFileArrKey.length, maxFileNum);
if (selectFileArrKey.length < maxFileNum && maxFileNum > 0) { // 文件数量限制
if (!selectFileArr.has(file.name)) { // 文件名未重复
var fileSize = file.size / 1048576;
if (selectFileSizeSum + file.size < maxFileSize * 1048576) { // 总文件大小限制
selectFileSizeSum += file.size; // 记录文件总大小
dragFile.addFile(file, fileSize.toFixed(2)); // 添加文件
} else {
tip('文件大小不能超过 ' + maxFileSize + ' MB', 1200, errTip);
}
} else {
tip('文件名重复', 1200, errTip);
}
} else {
tip('最多可选择 ' + maxFileNum + ' 个文件', 1200, errTip);
}
} else {
tip('不支持的文件格式', 1200, errTip);
}
},
// 列表显示
addFile: function(file, fileSize) {
var fileName = file.name; // 文件名
var showFileName = file.name; // 显示文件名
var tpFl = fileName.substr(fileName.lastIndexOf('.')); // 后缀
if (fileName.length > 16 + tpFl.length) { // 超过长度则截取
showFileName = fileName.substring(0, 16) + '……' + tpFl;
}
selectFileArr.append(file.name, file); // 添加文件
selectFileArrKey.push(file.name); // 记录文件名
dragFileTip.hide(); // 隐藏提示文字
updateShowFileName(); // 更新显示
var str = "<div class=\"drag_file_selectfile\" contenteditable=\"false\">" +
"<div class=\"select_filename\"><span>文件名</span>" + showFileName + "</div>" +
"<div class=\"select_filesize\"><span>文件大小:</span>" + fileSize + 'MB' + "</div>" +
"<div class='select_file_clear' onclick=\"dragFile.removeFile('" + fileName + "', this)\"></div></div>";
$('#drag_file_div').append(str);
},
// 移除文件
removeFile: function(fileName, that) {
fileName = fileName.trim();
if (selectFileArr.has(fileName)) {
selectFileArr.delete(fileName); // 移除数据
$(that).parent().remove(); // 找到父元素并删除
// 去除删除元素Key
var tpSfakArr = [];
for (let k in selectFileArrKey) {
if (selectFileArrKey[k] != fileName)
tpSfakArr.push(selectFileArrKey[k]);
}
selectFileArrKey = tpSfakArr;
updateShowFileName(); // 更新显示
tip('文件 【 ' + fileName + ' 】 移除成功', 2000, {});
}
if (selectFileArrKey.length <= 0) {
$('.drag_file_div_p').show(); // 显示提示文字
}
},
// Url事件截停
evStop: function(e) {
var ev = e || window.event;
ev.preventDefault();
ev.stopPropagation(); // Fiefox兼容
},
// 重置
reset: function() {
selectFileArr = new FormData(); // 选中文件数
selectFileArrKey = []; // 选中文件数
dragFileDiv = null; // 显示对象_主体盒子
dragFileTip = null; // 显示对象_提示内容
$('#select_file_addFile').reset();
}
} /**
* 更新文件名显示
*/
function updateShowFileName() {
if (selectFileArrKey.length > 0) {
// var fileSpanFileName = selectFileArrKey.join(' / ');
// $('#file_span').text(fileSpanFileName.length <= 24 ? fileSpanFileName : fileSpanFileName.substring(0, 24) + ' ……');
$('#drag_file_control>p').text('选择了' + selectFileArrKey.length + '个文件'); // 添加显示
} else {
// $('#file_span').text('暂未选择文件');
$('#drag_file_control>p').text('暂未选择文件'); // 添加显示
$('#drag_file_div>div').remove();
$('.drag_file_div_p').show(); // 显示提示文字
}
} /**
* 拖拽移动
* @param obj 目标对象 / #id / .class
* @param moveOut 是否可以移出边界
*/
function dragMove(dom, moveOut) {
var obj = $(dom);
moveOut = moveOut || false;
obj.bind('mousedown', start);
var deltaX = 0,
deltaY = 0; function start(e) {
var ol = obj.offset().left;
var ot = obj.offset().top;
deltaX = e.pageX - ol;
deltaY = e.pageY - ot;
$(document).bind({
'mousemove': move,
'mouseup': stop
});
return false;
} function move(e) {
var tpX = 0,
tpY = 0;
if ((e.pageX - deltaX > 0 && e.pageY - deltaY > 0) || moveOut) {
tpX = e.pageX - deltaX;
tpY = e.pageY - deltaY;
} else if (e.pageX - deltaX <= 0 && e.pageY - deltaY > 0) {
tpX = 0;
tpY = e.pageY - deltaY;
} else if (e.pageX - deltaX > 0 && e.pageY - deltaY <= 0) {
tpX = e.pageX - deltaX;
tpY = 0;
}
obj.css({
"left": (tpX),
"top": (tpY)
});
return false;
} function stop() {
$(document).unbind({
'mousemove': move,
'mouseup': stop
});
}
} /**
* 提示
* @param {Object} msg
* @param {Object} t
* @param {Object} style 自定义样式,必须是json格式
*/
function tip(msg, t, style) {
var tipId = 'tip' + (new Date().getTime());
var styleto = '';
if (!isNull(style)) {
for (var s in style) {
styleto += s + ': ' + style[s] + ';';
}
}
$('body').append("<div id='" + tipId + "' class='tip' style='" + styleto + "'>" + msg + "</div>");
setTimeout(function() {
$('#' + tipId).addClass('tipKill');
setTimeout(function() {
$('#' + tipId).remove();
}, t);
}, t);
} /**
* 空判断
* @param {Object} obj
*/
function isNull(obj) {
return obj == null || obj == undefined || obj == '' || obj == NaN || ('' + obj) == '{}';
}

5.效果图

基于作者 “三宝鸭” 代码重构,实现了高度动态化

理了一下逻辑和注释,增强了兼容性,大家仍可以 diy 成更适合自己的模块

参考链接:原生 JS 写拖拽文件上传_三宝鸭的博客-CSDN博客

转载请附上本文链接

Jq /Js 拖动选择文件的更多相关文章

  1. 通过js获得选择文件的绝对路径

    <form name="thisform" method="get" action="test.jsp" id="thisf ...

  2. JS 多选文件或者选择文件夹

    <%--文件多选--%> <input type="file" name="file" id="file" multipl ...

  3. js选择文件夹路径

    该方法只支持IE. 语法:strDir=Shell.BrowseForFolder(Hwnd,Title,Options,[RootFolder])参数:Hwnd:包含对话框的窗体句柄(handle) ...

  4. MVC学习随笔----如何在页面中添加JS和CSS文件

    http://blog.csdn.net/xxjoy_777/article/details/39050011 1.如何在页面中添加Js和CSS文件. 我们只需要在模板页中添加JS和CSS文件,然后子 ...

  5. 基于uploadify.js实现多文件上传和上传进度条的显示

    uploadify是JQuery的一个插件,主要实现文件的异步上传功能,可以自定义文件大小限制.文件类型.是否自动上传等属性,可以显示上传的进度条.官网地址是http://www.uploadify. ...

  6. [转][前端优化]使用Combres合并对js、css文件的请求

    本文转自:http://www.cnblogs.com/parry/archive/2011/01/28/Reduce_Http_Request_Using_Combres_For_Js_Css.ht ...

  7. 使用ajaxfileupload.js上传文件

    一直以来上传文件都是使用form表单上传文件,也看到过有人使用js上传文件,不过看起来蛮简单的也就没有怎么去理会.今天突然要使用这种方式上传文件,期间还遇到点问题.因此就记录下来,方便以后遇到这样的问 ...

  8. 【翻译】Microsoft Ajax Minifier 快速使用指南(与VS集成使用) 编译后直接压缩项目的JS或CSS文件

    网上找了好久终于找到一个能跟VS集成使用的JS和CSS压缩工具,因为害怕忘记,所以给转发过来,顺便翻译一下,大学那会儿学的英语基本上都已经还给老师了,所以翻译的不太好,不过能看懂就成,对吧? 原文地址 ...

  9. ssi-uploader上传图片插件,点击选择文件按钮自动提交表单解决办法

    先介绍一下这款插件,然后再谈使用中可能遇到的问题 ssi-uploader是一个JQuery的图片上传插件,界面比较美观 github地址:https://github.com/ssbeefeater ...

  10. document.activeElement 过滤选择文件弹窗导致的页面失焦

    在线考试页面,常常需要检测用户是否作弊. 一般是监听页面是否失焦的方式,而失焦的方式有很多种,比如QQ弹窗,切换页面,切换程序,input文件上传选择文件等 选择文件是正常情况,这种情况下需要过滤 本 ...

随机推荐

  1. HTTPS实现原理分析

    概述 在上一节中介绍了两种加密方法 对称加密 非对称加密 其中对称加密性能高,但是有泄露密钥的风险,而非对称加密相反,加密性能较差,但是密钥不易泄露,那么能不能把他们进行一下结合呢? HTTPS采用混 ...

  2. 【算法训练营day7】LeetCode454. 四数相加II LeetCode383. 赎金信 LeetCode15. 三数之和 LeetCode18. 四数之和

    [算法训练营day7]LeetCode454. 四数相加II LeetCode383. 赎金信 LeetCode15. 三数之和 LeetCode18. 四数之和 LeetCode454. 四数相加I ...

  3. mujoco d4rl 安装问题

    最近mujoco免费了,属实爽歪歪,安装d4rl没有以前那么麻烦了(不知为何半年前我安装d4rl时走了那么多弯路) mujoco安装 在 https://mujoco.org/download 上面下 ...

  4. Ajax的使用(jquery的下载)

    Ajax学习笔记(jquery的下载) JQuery的官网下载 地址:http://jquery.com 右上角的"Download JQuery" 三个可供下载的文件: Prod ...

  5. C# Linq 查询汇总

    分组取值.求和.计数 1 var resultlist = orderllist.GroupBy(oo => new { oo.Deptname, oo.Userid, oo.Username ...

  6. Spring源码知识

    bean的生命周期: 实例化:在堆空间中申请内存,使用反射来实现:(createBeanInstance) 自定义属性赋值(setter).容器对象属性赋值(invokeAwareMethods) 前 ...

  7. Django系列---开发三 前后端分离

    数据交互接口规范REST,全称 Representational State Transfer,意为"表现层状态转化". django的第三方拓展--django-rest-fra ...

  8. 部署redis

    1. 下载redis 下载地址:https://redis.io/download/ 下载版本:6.2.7 应用包:redis-6.2.7.tar.gz 2. 上传服务器并解压 将redis安装包上传 ...

  9. OpenCvSharp的安装和使用

    OpencvSharp是opencv的C#版本,使用习惯了opencv的人学起OpenCvSharp会很容易上手,看了网上很多的安装方式,最后我感觉还是自己去下载安装包的方式最简单,通过Nuget的方 ...

  10. 推荐三个实用的 Go 开发工具

    孙悟空在花果山称王的时候,特意去了一趟东海,在那里淘到了如意金箍棒.因为身为一个山大王,怎么能没有一件趁手的兵器呢? 作为程序员的我们也一样,除了我们的傍身武器 Ctrl C + V 之外,还要不停的 ...