门户中需要利用纯html实现拖拽/点击上传文件,本文章所举的例子需要实现的效果如下图:
1、HTMl
1.1 radio按钮的实现
将原生的radio外层包一层div,改为button的样式,隐藏radio,label的宽度拉满div,这样鼠标点击按钮时即使radio隐藏了,也能通过点击label触发对radio的监听事件,改变底部文档链接或者上传文件的显隐
1.2 点击虚线框上传文件的实现
点击文件框drop-area,触发对<input type="file">标签的点击效果,这里需要注意 <input type="file">标签要放到文件框#drop-area外面隐藏,否则对#drop-area点击后再触发<input type="file">的点击效果会造成无限循环。
#fileMassage为文件的校验提示。
#fileName为文件列表,由于这里设置了只上传一个文件,所以这里只写了简单的显示一个名字,右侧显示上传成功图标。
<--外层为对话框,这里不写了-->
<form class="el-form" id="docForm">
<div style="padding: 10px 5px">
<label for="docType" class="mr-10">文档类型:</label>
<div class="btn-radio">
<input type="radio" id="docTypeLink" name="docType" value="link" checked>
<label for="docTypeLink">链接</label>
</div>
<div class="btn-radio">
<input type="radio" id="docTypeFile" name="docType" value="file">
<label for="docTypeFile">文件</label>
</div>
</div>
<div id="urlInput" style="display: block;padding: 10px 5px;flex: 1">
<label for="url" class="mr-10">文档链接:</label>
<input type="text" id="url" name="url" style="border: 1px solid #EDF0F4;height: 33px;width: calc(100% - 90px);" class="d-inline-block"><br>
<span class="urlMessage" style="color: red;display: none;margin-left: 75px">请输入文档链接!</span>
</div>
<div id="fileInput">
<div id="drop-area">
<img src="/static/content/images/best-practice/upload-plus.png" style="margin:auto;display: block"/>
将文件拖到这里,或
<span style="color: #0066FF">点击上传文件</span>
</div>
<input type="file" id="file" name="file" accept=".doc,.docx" style="display: none">
<span class="fileMessage" style="color: red;display: none;height: 20px;margin-top: 10px;"></span>
<div id="fileName" style="height: 20px;margin-top: 10px;">
<span></span>
<div class="uploadSuccess d-inline-block"></div>
</div>
</div>
<div style="text-align: right" class="mt-20">
<input type="button" value="取消" class="primaryBtn mr-10" id="closeBtn" style="border: 1px solid #dcdfe6;min-width: 86px;">
<input type="button" value="提交" class="primaryBtn primary" id="submitBtn">
</div>
</form>
2、CSS
.btn-radio {
display: inline-block;
cursor: pointer;
padding: 3px 0px;
margin-right: -5px;
background-color: #f2f2f2;
border: 1px solid #ccc;
border-radius: 3px;
}
.btn-radio label {
width: 60px;
text-align: center;
cursor: pointer;
}
.btn-radio input[type="radio"] {
display: none; /* 隐藏实际的radio输入 */
}
.btn-radio input[type="radio"]:checked + label {
color: white;
}
.btn-radio:has(input[type="radio"]:checked) {
background-color: #0066FF;
}
/* 第一个.btn-radio的样式 */
.btn-radio:nth-of-type(1) {
border-radius: 5px 0px 0px 5px;
}
/* 第二个.btn-radio的样式 */
.btn-radio:nth-of-type(2) {
border-radius: 0px 5px 5px 0px;
}
#fileInput {
display: none;
padding: 10px 5px;
flex: 1;
display: flex;
flex-direction: column;
}
#drop-area {
flex: 1;
border: 1px dashed #aaa;
padding: 20px;
text-align: center;
font-size: 1.2em;
cursor: pointer;
}
#drop-area.highlight {
border-color: #007bff;
}
#docForm {
margin-top: 18px;
padding: 0px 10px;
height: calc(100% - 67px);
display: flex;
flex-direction: column;
}
#fileName {
cursor: pointer;
}
.uploadSuccess {
cursor: pointer;
margin-top: 2px;
width: 16px;
height: 16px;
float: right;
display: none;
background-image: url("/static/content/images/best-practice/upload-success.png");
}
.uploadSuccess.active {
background-image: url("/static/content/images/best-practice/delete-file.png");
}
.d-inline-block {
display: inline-block !important;
}
3、js+jquery
var fileId
var fileName
$(document).ready(function () {
// 初始化时根据文档类型显示/隐藏相关输入
showHideInputs();
// 监听url输入框,如果input有值,则隐藏提示信息;否则,显示提示信息
$('#url').on('change', function() {
var inputValue = $(this).val();
var errorMessage = $('.urlMessage');
if(inputValue.trim() !== '') {
errorMessage.hide();
} else {
errorMessage.show();
}
});
// 监听文档类型选择变化,控制表单文件链接或者上传文件的显隐
$('input[name="docType"]').change(showHideInputs);
var dropArea = $('#drop-area');
var uploadInput = $('#file');
// 拖放事件,文件拖入框内时,边框高亮
dropArea.on('dragenter', function(e) {
e.stopPropagation();
e.preventDefault();
$(this).addClass('highlight');
});
// 文件离开框内,边框移除高亮效果
dropArea.on('dragleave dragend drop', function(e) {
e.stopPropagation();
e.preventDefault();
$(this).removeClass('highlight');
});
// 文件在框内时,阻止浏览器默认事件,此监听必须设置,否则对drop的监听将失效
dropArea.on('dragover', function(e) {
e.stopPropagation();
e.preventDefault();
});
// 文件在框内放开时,获取文件,执行文件上传操作
dropArea.on('drop', function(e) {
e.stopPropagation();
e.preventDefault();
var files = e.originalEvent.dataTransfer.files;
$(this).removeClass('highlight');
handleFiles(files);
});
// 点击上传文件框,执行点击原生input标签的点击操作
dropArea.click(function(event) {
uploadInput.trigger('click');
});
// 通过点击上传时,文件输入框变化后,执行文件上传操作
uploadInput.on('change', function(e) {
var files = e.target.files;
handleFiles(files);
});
// 鼠标悬浮文件列表时,右侧显示删除图标,鼠标移开后,显示上传成功图标
$("#fileName").on('mouseenter', function() {
$('.uploadSuccess').addClass('active');
}).on('mouseleave', function() {
$('.uploadSuccess').removeClass('active');
});
// 鼠标点击文件右侧的图标时显示的一定是删除图标,点击后执行删除文件操作
$(".uploadSuccess").click(function() {
fileId = null
$('#fileName').hide()
})
// 上传文件操作
function handleFiles(files) {
// 获取文件输入框的文件
var file = files[0];
if (file) {
// 这里是限制文件类型为doc、docx,大小为100M
var fileType = ['application/msword', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document']
var isLt2M = file.size / 1024 / 1024 < 100
if (fileType.indexOf(file.type) < 0) {
$(".fileMessage").show().text("文件要求doc、docx!")
return
}
if (!isLt2M) {
$(".fileMessage").show().text("文件大小不能超过100MB!")
return
}
// 创建 FormData 对象
var formData = new FormData();
formData.append("file", file); // 将文件添加到 FormData 中
// 自定义其他表单字段也可以这样添加
formData.append("type", "doc");
formData.append("name", file.name);
fileName = file.name
// 发送 AJAX 请求到服务器
$.ajax({
url: "...", // 替换为你的上传接口URL
type: "POST",
data: formData,
headers: {
"Authorization": "Bearer ..." // 这里填入你的认证信息,例如 "Bearer {token}"
},
contentType: false, // 必须,告诉jQuery不要去设置Content-Type请求头
processData: false, // 必须,告诉jQuery不要去处理发送的数据
success: function(response) {
fileId = response.data.id // 存储fileId
$(".fileMessage").hide() // 文件消息提示隐藏
$('#fileName').show() // 显示文件列表
$('#fileName span').text(fileName) // 因为限制上传一个文件,所以简单显示文件名
},
error: function(jqXHR, textStatus, errorThrown) {
alert("文件上传失败: " + textStatus + " " + errorThrown);
}
});
}
};
// 提交按钮点击事件
$("#submitBtn").click(function(){
// 表单判空校验
var docType = $("input[name='docType']:checked").val();
var url = $("#url").val();
if (docType === 'link'&&!url) {
$(".urlMessage").show().text("请输入文件链接!")
return
}
if (docType === 'file'&&!fileId) {
$(".fileMessage").show().text("请上传文件!")
return
}
const params = {
sceneId,
docType,
fileId,
fileName,
url
}
$.ajax({
url: "...", // 替换为你的上传接口URL
type: "POST",
data: JSON.stringify(params),
headers: {
"Authorization": "Bearer ..." // 这里填入你的认证信息,例如 "Bearer {token}"
},
contentType: "application/json", // 必须,告诉jQuery不要去设置Content-Type请求头
success: function(response) {
... //后续可添加自己的操作,比如提示信息等等
},
error: function(jqXHR, textStatus, errorThrown) {
... //后续可添加自己的操作,比如提示信息等等
}
});
});
$("#closeBtn").click(closeDialog)
)};
// 根据选择的radio,控制文档链接或者文件上传的显隐
function showHideInputs() {
var isLink = $('#docTypeLink').is(':checked');
$('#urlInput').toggle(isLink);
$('#fileInput').toggle(!isLink);
}
// 打开对话框时,对表单进行初始化
function showDialog() {
fileId = null;
fileName = null;
$("#docTypeLink").prop("checked", true)
$("#docTypeFile").prop("checked", false)
showHideInputs()
$("#url").val('')
$(".urlMessage").hide()
$(".fileMessage").hide()
$('#fileName').hide()
$('#fileName span').text('')
... //打开对话框操作
}
function closeDialog() {
... //关闭对话框操作
}