记IE10 IE11 Edge的兼容问题
谨慎记录老版Edge, IE10, IE11的深坑探索之旅.
一句话描述的bug
IE中SVG图标classList是nullIE中使用new URL需要polyfill支持,推荐npm包IE中不能直接使用new Event,需要polyfill支持
fetch
babel-polyfill并未包含fetch函数,可以引入whatwg-fetch库,这是地址.
在IE中,ajax请求默认会被缓存,即使服务端并未要求缓存.可以在浏览器请求头headers里去缓存解决,代码如下:
const headers = new Headers;
headers.append('pragma', 'no-cache');
headers.append('cache-control', 'no-cache');
<input type="file" />
在IE中被点中后可能会出现一个闪烁光标,可以使用font-size: 0去除光标.
在IE中如果两次选中相同文件,不会触发change事件.当只需兼容IE11时,可以使用value = ''解决,代码如下:
function onChange(e) {
if(e.currentTarget.value === '') return;
// handle...
e.currentTarget.value = '';
}
在IE10中,不允许手动设置value值,可以动态创建,销毁input节点解决,代码如下:
// css
.common-hide-input-file {
display: none;
outline: none;
}
// js
function inputFile(accept, callback) {
// Same file can't dispatch "change" event in IE.
// <input type="file" class="common-hide-input-file" accept="image/*" />
const input = document.createElement('input');
input.type = 'file';
input.className = 'common-hide-input-file';
input.accept = accept;
input.addEventListener('change', function changeFile(e) {
const file = e.currentTarget.files[0];
callback(file);
document.body.removeChild(input);
input.removeEventListener('change', changeFile);
});
document.body.appendChild(input);
input.click();
}
<a download></a>
如果需要不经过服务器,以纯文本文件为例,浏览器直接下载文件有两种方法:
href设为base64串,前缀加data:text/plain,href设为blob值.
a标签设置download属性,值为下载的文件名.
js代码如下:
const downloadBtn = document.querySelector('a');
// IE an old version of Edge is not support.
// downloadBtn.download = filename;
// downloadBtn.href = 'data:text/plain,' + encodeURIComponent(content);
const blob = new Blob([content]);
// IE support
if (navigator.msSaveBlob) {
downloadBtn.onclick = function () {
navigator.msSaveBlob(blob, filename);
};
} else {
// URL.revokeObjectURL destroy "object url"
if (downloadBtn.href) {
URL.revokeObjectURL(downloadBtn.href);
}
downloadBtn.download = filename;
downloadBtn.href = URL.createObjectURL(blob);
}
<button></button>
在IE10中如果不设置type = "button",当焦点处于按钮上时,按下回车会再次触发click事件.
<canvas></canvas>
canvas可能不包含toBlob方法,手动兼容,代码如下(来源: MDN):
if (!HTMLCanvasElement.prototype.toBlob) {
Object.defineProperty(HTMLCanvasElement.prototype, 'toBlob', {
value: function (callback, type, quality) {
var binStr = atob(this.toDataURL(type, quality).split(',')[1]),
len = binStr.length,
arr = new Uint8Array(len);
for (var i = 0; i < len; i++) {
arr[i] = binStr.charCodeAt(i);
}
callback(new Blob([arr], { type: type || 'image/png' }));
}
});
}
NodeList对象
document.querySelector返回的nodeList对象可能不包含forEach方法,手动兼容,代码如下(来源: MDN):
if (window.NodeList && !NodeList.prototype.forEach) {
NodeList.prototype.forEach = Array.prototype.forEach;
}