动态插入媒体标签时,onerror内联写法易失效,应创建元素后、设src前用addEventListener绑定错误处理,闭包捕获元素引用,fallback前先置空src,并预加载降级资源。

循环生成的 、 或 标签,不能靠统一写死 onerror="this.src='...'" 来兜底——因为动态插入时事件绑定时机错位、路径拼接出错、或重复触发导致内存泄漏,是高频崩点。
动态插入前必须显式绑定 error 事件
用 innerHTML += ' 拼接,
'onerror 在标签插入 DOM 后才解析,但此时图片可能已开始加载甚至失败,事件直接丢失。浏览器不会补发。
- 正确做法:创建元素后、设置
src前,先用addEventListener('error', handler)绑定 - handler 必须闭包捕获当前元素引用,避免循环中
this指向错乱 - 不要在 handler 里直接写
el.src = fallback,先设el.src = ''再赋值,防止浏览器跳过请求(尤其 CDN 缓存了 404 响应)
模板字符串里写内联 onerror 的致命陷阱
看似方便的写法:`,实际极易失效。`
-
fallback路径若含空格、中文或相对路径(如./img/def.png),在不同 base URL 下解析失败,二次加载又 404,浏览器静默阻止后续onerror - 字符串插值无法保证
fallback是已预加载资源,用户首次看到白屏或裂图 - 推荐改用绝对路径或 data URL:
data:image/svg+xml;base64,PHN2Zy...,彻底规避路径风险
循环中防 fallback 无限重试
每个媒体元素独立失败,但共享同一套降级逻辑时,容易因状态未隔离引发连锁反应。
- 给每个元素加唯一
data-id或data-src-index,在 handler 中记录“该 URL 已尝试 fallback X 次”,超过 2 次就停手 - 避免用 class 名或 DOM 位置判断目标元素——模板重渲染后索引错位,
querySelector('.item:nth-child(2)')会选错 - 对
和,onerror触发条件比更严格(如网络中断、格式不支持、CORS 阻塞均触发),但无法区分是 poster 图失败还是视频本身失败,建议 poster 单独用+onerror保护
Vue/React 等框架里别碰 this.src
框架控制 DOM 更新节奏,直接操作原生 src 属性会绕过响应式系统,轻则闪烁,重则触发无限 re-render。
- Vue:用
@error.once+ref,在回调中调用this.$nextTick(() => this.$refs.mediaEl.src = fallback) - React:onError 回调中先检查
e.target.src !== fallbackUrl,再赋值,否则 props 更新后可能再次进入 onError - 两者都必须提前预加载 fallback 资源:
const img = new Image(); img.src = fallbackUrl;,否则 fallback 时刻仍要等网络
最易被忽略的是:循环生成的媒体标签,其 loading="lazy" 在 Safari 和部分 Android WebView 中,若父容器初始 display: none 或处于折叠区域,会彻底跳过加载——哪怕后来显示出来也不会补触发。必须确保首屏关键媒体不懒加载,且 fallback 资源本身不依赖懒加载逻辑。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











