loop属性必须写为布尔属性(如或videoEl.loop=true),autoplay+loop必须配合muted才能生效,iOS上loop常失效,需用ended事件手动重播并真机测试。

直接加 loop 和 muted 就能实现静音循环播放,但浏览器是否真按你写的执行,得看属性写法、加载时机、设备类型——尤其 iOS 上,loop 常被静音策略连带失效。
loop 属性必须写成布尔属性,不能赋值
loop 是原生布尔属性,只认“有没有”,不认“值是什么”。写成 loop="true"、loop="1" 或 loop=""(空字符串)在部分浏览器里可能意外生效,但不可靠;写成 loop="false" 则完全无效——浏览器根本不解析这个值。
正确写法只有两种:
-
<video loop></video>(静态启用) -
videoEl.loop = true(JS 动态启用,注意必须是布尔值true,不是字符串)
常见错误是用 setAttribute('loop', 'true'),这只会把属性当字符串塞进 DOM,videoEl.loop 读出来仍是 false。
立即学习“前端免费学习笔记(深入)”;
autoplay + loop 必须配 muted,否则大概率被拦截
Chrome、Firefox、Edge、Safari 全部要求:自动播放(autoplay)的视频,若带声音,会被静默阻止。即使写了 loop,只要没 muted,autoplay 根本不会触发,自然也轮不到循环。
所以背景视频这类场景,必须三者共存:
-
autoplay:触发初始播放 -
muted:绕过自动播放限制 -
loop:让结尾跳回开头
额外建议加上 playsinline(iOS Safari 防止全屏)、preload="metadata"(减少首帧等待),避免白屏卡顿。
iOS Safari 上 loop 可能不工作,ended 事件是兜底方案
iOS Safari 对 loop 的支持不稳定,尤其在微信内置浏览器或某些 WebView 中,即使加了 muted 和 autoplay,视频播完也可能停在末帧不动。
此时监听 ended 事件手动重播更可靠:
const video = document.querySelector('video');
video.addEventListener('ended', () => {
video.currentTime = 0;
video.play().catch(e => console.warn('自动重播被阻止:', e));
});
注意两点:
-
video.play()返回 Promise,失败时会 reject,需catch处理(比如用户未交互过,iOS 可能拒绝后续play()) - 不要在
ended里只设currentTime = 0就结束,不调play()视频不会继续
JS 动态切换 loop 状态,不会中断当前播放周期
如果视频正在播放中执行 video.loop = false,它不会立刻停止,而是等当前这一遍播完才退出循环;同理,video.loop = true 也不会让已暂停的视频自动恢复。
想立刻生效,得配合其他操作:
- 关闭循环并立即停在末尾:
video.loop = false; video.pause(); - 开启循环后强制重播:
video.loop = true; video.currentTime = 0; video.play();
另外,video.loop 的值和元素是否有 loop 属性不一定同步——比如用 JS 设置 video.loop = true,video.hasAttribute('loop') 仍返回 false,因为属性没写进 HTML。判断是否生效,应以 video.loop 的布尔值为准。
真正难的不是写对属性,而是验证它在各种设备上是否真在循环:iOS 微信、Android Chrome、旧版 Edge……每个环境都可能悄悄忽略 loop。上线前务必在真机上测 ended 事件是否触发、重播是否无缝、静音按钮能否正常开关。


















