video loop 必须为布尔属性且需配合 muted 和 autoplay 才能可靠生效;ios 还需 playsinline 并真机测试;有声或需精细控制时应改用 ended 事件手动重播。

loop 属性必须写成布尔属性,不能带值
浏览器只检查 loop 这个属性是否存在,不读取它的值。写成 <video loop="true"></video>、<video loop="1"></video> 或 <video loop=""></video> 在多数现代浏览器里都无效——哪怕它偶尔“看起来”能循环,也是偶然行为,不可依赖。
正确写法只有两种:
-
<video loop src="bg.mp4"></video>(静态 HTML 中直接写属性) -
videoEl.loop = true(JS 动态设置,必须是布尔值true,不是字符串)
用 videoEl.setAttribute('loop', 'true') 也完全没用:它只是往 DOM 上加了个带值的字符串属性,videoEl.loop 读出来仍是 false。
muted 是 autoplay + loop 能生效的前提
Chrome、Edge、Firefox、Safari 全部拦截未静音的自动播放。如果视频有声,autoplay 会被静默阻止,视频卡在第一帧,loop 根本没机会启动。
所以背景视频这类场景,三者必须共存:
-
autoplay:触发初始播放 -
muted:绕过自动播放限制 -
loop:让结尾跳回开头
漏掉 muted,loop 就是摆设;加了但写成 muted="muted" 或 muted="true",虽部分浏览器兼容,但不符合规范,建议统一用布尔写法 <video muted></video>。
iOS Safari 上 loop 常失效,必须加 playsinline 并真机测试
iOS Safari(含微信内置浏览器)对 loop 有硬性限制:即使用户已点过屏幕、视频已加载完成,若没同时满足 muted + autoplay + playsinline,原生 loop 很可能被忽略。
playsinline 防止 iOS 强制全屏跳转,破坏布局;它不是可选优化,而是必要条件。
典型可靠写法:
<video loop muted autoplay playsinline src="bg.mp4"></video>
注意:仅靠这个组合还不够,必须在真机上测试——模拟器常误报“正常”,而实际设备上仍可能卡顿或跳帧。
需要开声音或精细控制时,改用 ended 事件手动重播
如果视频必须有声、或需在循环前做清理/延迟/换源,原生 loop 就不适用了。此时监听 ended 事件手动重播更可控:
video.addEventListener('ended', () => {
video.currentTime = 0;
video.play().catch(e => console.warn('重播被阻止:', e));
});
关键细节:
-
video.play()返回 Promise,失败时会 reject,必须catch,否则报错打断逻辑 - 仅设
currentTime = 0不调play(),视频不会动 - 若用户尚未与页面交互过,iOS/Chrome 可能直接拒绝
play(),得引导点击授权
手动重播比原生 loop 多一层控制权,但也多一层出错可能——比如 Promise 拒绝后没处理,就再也播不起来了。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











