记IE10 IE11 Edge
的兼容问题
谨慎记录老版Edge, IE10, IE11的深坑探索之旅.
一句话描述的bug
IE
中SVG
图标classList
是null
IE
中使用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; }