附件上传在IE中的问题
问题描述:自定义的文件上传
input:file
在IE浏览器上进行附件上传时,input:file
的onchange
事件失效。
原因分析:
input:file
控件的onchange
事件实际上监听的是input
框中的字符串的变化,如果字符串没有发生变化,则不会触发onchange
事件。input:file
控件在IE浏览器上会缓存上次添加的文件,导致再次上传同一个文件时onchange
事件不能正常触发,即使刷新页面缓存还在。input:file
控件在IE浏览器中,通过js
绑定input:file
的onchange
事件const file = document.getElementById('file');file.click();file.onchange = function (event) {}
,如果添加了属性hidden
或者 添加了样式display: none
,或者opacity: 0
,则onchange
事件都会失效。
解决方法
在 vue 中的示例:
<template>
<div>
<el-button
type="primary"
size="small"
@click="handleUpload">附件上传</el-button>
<input
ref="file"
type="file"
id="file"
name="file"
hidden
@change="handleFileChange">
</div>
</template>
export default {
methods: {
handleUpload() {
const element = this.$refs.file
element.click()
},
handleFileChange(event) {
const file = event.target.files[0]
if (file) {
// ...
}
}
}
}
其他参考方案
网上的几种可供参考的方法如下:
- 使用
position: absolute; top: 0;left: 0;
。 - 使用
height: 0; overflow: hidden;
。 - 使用
input:file
克隆,每次附件上传成功后 克隆一份input:file
,移除旧的input:file
控件,植入新的input:file
控件,实际上就是先删除原来的input:file
控件,然后在原位置上放置一个新的input:file
,目的就是为了阻止浏览器缓存 附件。 - 在触发附件上传的按钮上放置 input:file 控件,并将控件设置 透明,点击按钮实际上是点击的 input:file 控件,这样可以解决问题,但是鼠标样式会影响用户体验。