link.onload不可靠,因safari(截至17.6)完全不触发该事件,且200响应但空内容或mime错误时也不触发;需组合onload/onerror监听、getcomputedstyle轮询测试元素样式生效、5秒超时兜底三重保障。

link.onload 不可靠,Safari 完全不触发它;仅靠 document.styleSheets 也判不准——跨域、空文件、语法错误都会导致误判。真正能落地的方案,是组合事件监听 + 样式生效检测 + 超时兜底。
为什么不能只用 link.onload
Chrome/Firefox/Edge 支持 link.onload,但 Safari(截至 17.6)完全不派发该事件,只响应 onerror。这不是 bug,而是规范未强制要求,Safari 选择不实现。
这意味着:代码里写了 link.onload = () => resolve(),在 Safari 下 Promise 永远不会 resolve,直接卡死。
更糟的是,某些服务器返回 200 但内容为空、或 MIME 类型错误(如返回 HTML),onload 也不会触发——你得靠 onerror 和超时共同捕获。
怎么写一个跨浏览器可用的加载函数
核心逻辑分三路并行:onerror 一触发就 reject;Chrome/Firefox/Edge 的 onload 触发即 resolve;无论事件是否发生,都启动样式检测逻辑(带超时)。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 插入
link前必须绑定onload和onerror,否则旧版 Safari 或快速加载场景会漏掉事件 - 准备一个极简测试元素(比如
<div id="css-test"></div>),并在目标 CSS 中定义唯一规则:#css-test { opacity: 0.001; } - 用
getComputedStyle轮询该元素的opacity,匹配到"0.001"即视为样式已生效(注意:必须确保测试元素已挂载到document.body) - 轮询间隔用
requestAnimationFrame,比setTimeout更稳;超时设为 5 秒,避免无限等待
document.styleSheets 为什么不能当判断依据
这个 API 返回的是 DOM 中所有 <style></style> 和 <link> 对应的样式表列表,但它不反映真实加载状态:
- 跨域 CSS 会出现在
document.styleSheets中,但读取其cssRules抛SecurityError,无法确认是否加载成功 - 即使 HTTP 返回 200,CSS 内容为空或含语法错误,
sheet.cssRules仍可能是空数组或null,轮询会永远等不到 -
document.styleSheets.length增加只说明<link>节点插入了 DOM,并不代表样式已解析或应用 - IE 低版本中
sheet属性可能延迟挂载,需配合attachEvent('onload'),但该行为已被现代标准废弃
@import 和内联样式根本没法监听
原生事件对 @import 完全无感:主 CSS 的 onload 触发后,里面 @import 的资源失败也不会通知你。内联样式(<style>...</style>)和 style 属性更没有加载概念,自然无事件可绑。
- 服务端尽量避免深度
@import,构建阶段用 PostCSS 或 Webpack 提前 inline 或合并 - 若必须动态处理,得先
fetch()主 CSS 内容,正则提取所有@import url(...),再逐个发起请求并监听——这已超出原生能力范围 - 跨域
@import还涉及 CORS,且无法被前端 JS 观测,只能靠服务端日志或监控平台排查
color 或 font-size 这类容易被继承或重置的属性,优先选 font-family: "css-loaded-9876"; 或 margin-top: 9999px; 这种几乎不可能被覆盖的声明。Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










