怎样使用JS判断某个外部CSS是否已加载完成

雨雪姑娘_6079

雨雪姑娘_6079

2026-09-17

218人浏览

原创

真正跨浏览器可用的方案是事件监听+超时兜底+属性轮询三重保障:onload/onerror需插入前绑定,5秒超时后轮询testel.opacity等稳定属性,避免依赖sheet.cssrules或单一事件。

怎样使用js判断某个外部css是否已加载完成

link.onload 不可靠,link.onerror 盲区大,单靠轮询 sheet.cssRules 会报跨域错误或在 Safari 下失效。真正能落地的方案是三者组合:事件监听 + 超时兜底 + 属性轮询。

为什么不能只用 link.onload

Chrome/Firefox/Safari 都要求 onload 必须在 link 插入 DOM 前绑定,否则事件可能永远不触发(尤其缓存命中时)。Safari 还存在 onload 永远 pending 的 bug,导致 Promise 卡死。IE 虽支持 attachEvent('onload'),但 404 时也会误触发,无法区分成功/失败。

  • link.onload = handler 必须写在 document.head.appendChild(link) 之前
  • 插入后才赋值,等于白写;加 setTimeout 延迟赋值也救不了竞态
  • 即使绑对了,Safari 仍可能不触发,必须有 fallback

为什么 link.onerror 不能当失败依据

onerror 只对明确的网络/解析错误敏感:404、CORS 阻断、MIME 类型错误(如返回 HTML)、CSS 语法错误。但它对以下情况完全沉默:

  • 网络中断或请求超时 → 无任何事件
  • Safari 加载失败时行为不一致,有时触发、有时不触发
  • 服务端返回 200 状态码,但响应体为空、乱码或 JSON → 样式无效,onerror 不触发
  • CDN 回源失败返回兜底页(如 Nginx 50x 页面)→ 200 + HTML 内容,onerror 完全失灵

怎样做才是跨浏览器可用的检测

用「事件监听 + 5 秒超时 + 属性轮询」三重保障,缺一不可:

抖音下载器(Node.js)
抖音下载器(Node.js)

抖音无水印视频下载和文案提取工具

下载
  • 插入前立即绑定 link.onloadlink.onerror
  • 同步启动一个 setTimeout(..., 5000),超时即进入轮询阶段
  • 轮询逻辑检查 link.sheet 是否存在,再尝试读取 link.sheet.cssRules(捕获 NS_ERROR_DOM_SECURITY_ERR);WebKit 下直接看 link.sheet 是否为非 null 对象
  • 轮询间隔设为 10ms,避免阻塞主线程;一旦确认加载完成,用 setTimeout(cb, 1) 微任务延迟回调,确保样式已应用

示例关键片段(不依赖框架):

function loadCss(src, cb) {
  const link = document.createElement('link');
  link.rel = 'stylesheet';
  link.href = src;

  let loaded = false;
  const done = (err, node) => {
    if (loaded) return;
    loaded = true;
    cb(err, node);
  };

  link.onload = () => done(null, link);
  link.onerror = () => done(new Error('CSS load failed'), link);

  document.head.appendChild(link);

  setTimeout(() => {
    if (loaded) return;
    // 开始轮询
    const poll = () => {
      try {
        if (link.sheet && ('cssRules' in link.sheet || /webkit/i.test(navigator.userAgent))) {
          return setTimeout(() => done(null, link), 1);
        }
      } catch (e) {
        if (e.name === 'SecurityError') {
          return setTimeout(() => done(null, link), 1);
        }
      }
      setTimeout(poll, 10);
    };
    poll();
  }, 5000);
}

轮询时该检查哪个 CSS 属性最稳妥

别用 getComputedStyle(el).widthheight —— 容易被其他样式覆盖,结果不可靠。推荐用带副作用且不易被覆盖的属性:

  • getComputedStyle(testEl).opacity:默认为 '1',若 CSS 中显式设置了 opacity: 0.5,则可确认规则已生效
  • 提前在 CSS 中定义一个唯一 class,比如 .css-loaded-test { opacity: 0.001; },然后创建一个隐藏 <div class="css-loaded-test"></div>,轮询其 opacity 是否变为 '0.001'
  • 这个方法绕过 sheet.cssRules 的跨域限制,且在所有现代浏览器中行为一致

真正难的不是写轮询逻辑,而是意识到:CSS 加载状态无法被单一信号穷举。你得接受“没有银弹”,只能靠组合策略覆盖边缘 case —— 尤其是 Safari 和跨域场景,最容易掉坑里。

前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!

相关专题

更多
css
css

css是层叠样式表,用来表现HTML或XML等文件样式的计算机语言,不仅可以静态地修饰网页,还可以配合各种脚本语言动态地对网页各元素进行格式化。php中文网还为大家带来html的相关下载资源、相关课程以及相关文章等内容,供大家免费下载使用。

2023.06.15

3756

6

css居中
css居中

css居中:1、通过“margin: 0 auto; text-align: center”实现水平居中;2、通过“display:flex”实现水平居中;3、通过“display:table-cell”和“margin-left”实现居中。本专题为大家提供css居中的相关的文章、下载、课程内容,供大家免费下载体验。

2023.07.27

837

5

css如何插入图片
css如何插入图片

cssCSS是层叠样式表(Cascading Style Sheets)的缩写。它是一种用于描述网页或应用程序外观和样式的标记语言。CSS可以控制网页的字体、颜色、布局、大小、背景、边框等方面,使得网页的外观更加美观和易于阅读。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.07.28

1678

6

css超出显示...
css超出显示...

在CSS中,当文本内容超出容器的宽度或高度时,可以使用省略号来表示被隐藏的文本内容。本专题为大家提供css超出显示...的相关文章,相关教程,供大家免费体验。

2023.08.01

3026

7

css字体颜色
css字体颜色

CSS中,字体颜色可以通过属性color来设置,用于控制文本的前景色,字体颜色在网页设计中起到很重要的作用,具有以下表现作用:1、提升可读性;2、强调重点信息;3、营造氛围和美感;4、用于呈现品牌标识或与品牌形象相符的风格。

2023.08.10

5865

11

什么是css
什么是css

CSS是层叠样式表(Cascading Style Sheets)的缩写,是一种用于描述网页(或其他基于 XML 的文档)样式与布局的标记语言,CSS的作用和意义如下:1、分离样式和内容;2、页面加载速度优化;3、实现响应式设计;4、确保整个网站的风格和样式保持统一。

2023.08.10

5011

7

css三角形怎么写
css三角形怎么写

CSS可以通过多种方式实现三角形形状,本专题为大家提供css三角形怎么写的相关教程,大家可以免费体验。

2023.08.21

1757

9

css设置文字颜色
css设置文字颜色

CSS(层叠样式表)可以用于设置文字颜色,这样做有以下好处和优势:1、增加网页的可视化效果;2、突出显示某些重要的信息或关键字;3、增强品牌识别度;4、提高网页的可访问性;5、引起不同的情感共鸣。

2023.08.22

2371

5

css禁止点击事件
css禁止点击事件

实现css禁止点击事件的方法有使用CSS的pointer-events属性和使用JavaScript禁用点击事件。本专题为大家提供点击事件相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.23

2013

5

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Sass 教程
Sass 教程

共14课时 | 1.4万人学习

Bootstrap 5教程
Bootstrap 5教程

共46课时 | 5.5万人学习

CSS教程
CSS教程

共754课时 | 93.1万人学习