onerror中直接换src会导致无限循环,因备用图404时会再次触发同一onerror;必须先换src再置this.onerror=null,且需用分号隔开,推荐绝对路径或data:URL,并用dataset标记状态防误触。

onerror里直接换src为什么会导致无限循环
因为浏览器在加载新 src 失败时,会再次触发同一个 onerror 回调——如果备用图也 404,就会形成“换图 → 失败 → 再换图 → 再失败”的死链。内存持续增长,DevTools 可能卡死,页面无响应。
必须写this.onerror = null切断事件绑定
这是防循环的硬性操作,不是可选项。顺序不能错,且必须用分号隔开:
onerror="this.src='/img/placeholder.svg'; this.onerror=null;"- 不能写成
onerror="this.onerror=null; this.src='...'"(还没换图就清空了,白忙) - 不能省略分号,否则 JS 解析可能出错(尤其老 Safari)
- 推荐用绝对路径或
data:URL,避免 fallback 图自身路径再出问题
用dataset打标比onerror=null更可控
当需要多次降级、或 fallback 图本身也要走逻辑判断时,仅靠 onerror=null 不够灵活。用自定义标记能明确状态:
onerror="if (!this.dataset.fallbacked) { this.dataset.fallbacked = '1'; this.src = '/img/fallback.png'; }"- 后续还可扩展:比如根据
dataset.attempt计数,三次失败后显示文字提示 - 动态插入的
必须在appendChild()前就设好dataset初始值,否则首次错误已发生
哪些情况onerror根本不会触发,别白忙
很多“图片没显示”根本进不了 onerror,查半天代码发现是路径或配置问题:
-
src=""或src=" ":浏览器不发请求,不触发 - 跨域图没加
crossorigin属性:CORS 阻塞只报错,不进onerror - 服务器返回 200 + 占位 HTML(如某些 CDN 的 404 页面):请求成功,不算失败
-
src是相对路径,本地开发时解析为file://下的错误路径:先检查地址栏能否直接打开那个 URL
真正闭环的降级,从来不是“写了 onerror 就完事”,而是从路径可靠性、事件触发边界、状态标记三处同时收口。最容易被跳过的,其实是第一层:确认主图 src 本身是否真能访问。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











