YeaseonZhang

移动端文件上传美化&一键上传

最近项目中文件系统需要适配移动端,发现很多PC端的交互在移动端显得很累赘。

下面就改造一下文件上传,让它变得更加适合移动端。

PC端实现方案

就拿上传文件来说,之前在移动端是点击上传icon,弹出一个对话框选择文件,然后通过对话框的按钮进行上传。

分解起来就是,选择文件和上传文件,其实是两步。但是在移动端,我们点击input[file]会调用原生的文件系统(iOS是选择照片/拍照上传),
百度云的做法是在调用原生的文件系统,选择完要上传的文件,无需用户点击上传按钮直接上传。现在我们来学习下百度云的做法。

美化input控件

在没有使用插件的原生input[file]是很难看的,上面的PC端上传文件是使用了file-input组件,
所以我们自定义样式之后会显得比较好看。

但是在移动端我们不使用弹框效果了,所以input[file]也就没必要美化,直接隐藏就好。通过上传按钮调用input[file]

1
2
3
4
5
6
7
8
9
// HTML
<span class="upload" onclick="chooseFile()"></span>
<input type="file" accept="*/*" name="uploadFile" style="display: none; opacity: 0"/>

// JS
function chooseFile() {
var fileObj = document.getElementsByName('uploadFile')[0];
fileObj.click();
}

在上面的代码中,我们使用一个上传icon触发input[file]这样文件就选择完毕了

一键上传

现在文件选择完成了,我们发现没有办法上传文件了,因为input[file]已经被我们隐藏了。

让我们来转换一下思维方式,为什么还需要第二步上传操作,我们不能选择完成之后直接上传吗?事实证明百度云就是这么做的。

input[file]也是一个普通的input,那我们就能使用它的change事件,这样就把思路捋顺了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// HTML
<span class="upload" onclick="chooseFile()"></span>
<input type="file" accept="*/*" name="uploadFile" onchange="uploadFile()" style="display: none; opacity: 0"/>

// JS
function chooseFile() {
var fileObj = document.getElementsByName('uploadFile')[0];
fileObj.click();
}

function uploadFile() {
var formData = new formData();
var fileObj = document.getElementsByName('uploadFile')[0].files[0];
formData.appenf('file', fileObj);

axios.post(url, formData)
.then(function (res) {
// success
})
.catch(function () {
// error
})
}

input[file]添加一个change事件,就能在我们选择完文件,自动调用相关函数进行上传。
在这里我没有使用原生的AJAX,我使用的是axios,感兴趣的话可以自行Google。

结语

至此,我们就实现了一个简单移动端的上传文件,还有很多不足,会在后续工作中优化。