IE11及Edge 40中<link>的preload onload事件失效,求兼容方案
你遇到的问题很典型:IE11和Edge 40这类旧浏览器完全不支持rel="preload"属性值,导致带preload的<link>元素既不会预加载资源,也不会触发onload事件。下面是几个经过验证的实用兼容方案:
方案1:特性检测+动态创建元素(推荐)
通过JavaScript检测浏览器是否支持preload,针对不同情况生成对应的<link>元素,这是最可靠的兼容性处理方式:
// 检测浏览器是否支持preload特性 const supportsPreload = 'relList' in document.createElement('link') && document.createElement('link').relList.supports('preload'); // 创建字体样式的link元素 const fontLink = document.createElement('link'); fontLink.href = 'https://fonts.googleapis.com/css?family=Montserrat:300'; if (supportsPreload) { // 支持preload的现代浏览器:先预加载资源,加载完成后转为样式表 fontLink.rel = 'preload'; fontLink.as = 'style'; fontLink.onload = function() { this.rel = 'stylesheet'; }; } else { // 不支持preload的旧浏览器:直接加载样式表 fontLink.rel = 'stylesheet'; } // 将元素添加到页面头部 document.head.appendChild(fontLink);
这种方式既能让现代浏览器享受preload的性能优化,又能让旧浏览器直接加载样式表,完全避免兼容性问题。
方案2:条件注释+noscript兜底(针对IE11和无JS环境)
对于IE11,可以利用它独有的条件注释直接加载样式表;对于其他不支持preload的浏览器(比如Edge 40),可以用noscript标签做兜底(覆盖用户禁用JS的场景),建议配合方案1的JS检测一起使用:
<!-- 现代浏览器:使用preload优化加载 --> <link href="https://fonts.googleapis.com/css?family=Montserrat:300" rel="preload" as="style" onload="this.rel='stylesheet'"> <!-- IE11专属:直接加载样式表 --> <!--[if IE 11]> <link href="https://fonts.googleapis.com/css?family=Montserrat:300" rel="stylesheet"> <![endif]--> <!-- 无JS环境或不支持preload的浏览器兜底 --> <noscript> <link href="https://fonts.googleapis.com/css?family=Montserrat:300" rel="stylesheet"> </noscript>
注意:Edge 40不支持IE条件注释,所以单独用这个方案无法覆盖Edge 40,必须配合方案1的JS检测才能实现全面兼容。
方案3:使用Preload Polyfill
可以引入专门的preload polyfill脚本,它会自动识别不支持preload的浏览器,将rel="preload"的元素转换为对应的资源加载方式(比如样式表就转为rel="stylesheet")。不过要注意选择体积小巧、性能影响低的polyfill,避免拖慢页面加载速度。
为什么原写法失效?
核心原因很简单:IE11和Edge 40根本不认识rel="preload"这个属性值,浏览器会直接忽略这个<link>元素的加载逻辑,自然不会触发onload事件;而当你设置有效的rel="stylesheet"时,浏览器能识别这是样式表资源,会正常加载并触发onload。
内容的提问来源于stack exchange,提问作者Paesano2000

