onerror卡死主因是src替换失败后无限触发自身,形成循环;须立即置null阻断,推荐内联写法onerror="this.src='fallback.png'; this.onerror=null;"并用base64备用图防路径问题。

onerror 为什么一写就卡死
因为备用图也加载失败时,onerror 会再次触发,形成无限循环:换 src → 请求失败 → 再触发 onerror → 再换 src……最终内存暴涨、页面无响应,甚至 DevTools 崩溃。这不是小概率事件——只要 fallback 路径写错、CDN 挂掉、或本地用 file:// 协议双击打开 HTML,就极可能命中。
最稳妥的内联写法必须带 this.onerror=null
内联写法是目前唯一跨浏览器稳定生效的方式(动态绑定在 Safari/旧 Edge 中常失效),但必须严格按顺序执行:
-
onerror="this.src='fallback.png'; this.onerror=null;"—— 分号不能少,this.onerror=null必须紧接在赋值之后 - 更防错的写法:
onerror="if (!this.src.includes('fallback')) { this.src='fallback.png'; this.onerror=null; }",避免已换过源还误触发 - fallback 图推荐用
data:image/svg+xml;base64,PHN2ZyB...这类内联 base64,彻底规避路径解析和跨域拦截风险
动态创建的 img 元素怎么防循环
JS 动态插入的 ,onerror 必须在 appendChild() 前绑定,否则首次加载失败根本捕获不到。且不能只靠 this.onerror=null,还得用 dataset 打标:
- 创建时立即设
img.dataset.loaded = '0' - onerror 回调里先递增:
const count = parseInt(img.dataset.loaded) || 0; if (count - 第 3 次直接设为透明占位图,并移除事件:
img.src = 'data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=='; img.onerror = null;
全局监听 error 事件的坑在哪
document.addEventListener('error', handler, true) 能覆盖动态图片,但极易误伤:
- 必须检查
e.target.tagName === 'IMG',否则script、link的错误也会进回调 - 第三个参数
true是必须的(捕获阶段),因为error事件本身不冒泡 - 要加
if (!e.target.dataset.handled)防重复处理,否则同一张图多次重试会反复执行 - 它无法替代内联
onerror:SSR 渲染的首屏图片,JS 还没执行时就已失败,只能靠 HTML 里写的内联逻辑兜底
真正容易被忽略的是:**90% 的“加载失败”根本不是 onerror 没写对,而是 src 路径一开始就没解析对——尤其在嵌套路由、构建后路径偏移、或 file:// 协议下。先看 Network 面板里 Request URL 发去了哪,再动手改 JS。**
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











