我正在研究一个自定义组件,偶然发现了这种奇怪的行为。基本上,可以完全不向DOM添加<video>
元素的情况下播放视频文件。
const video = document.createElement('video');
video.src = "https://upload.wikimedia.org/wikipedia/commons/transcoded/c/c6/Video_2017-03-19_23-01-33.webm/Video_2017-03-19_23-01-33.webm.480p.webm";
function start()
{
if (video.paused)
{
video.play();
console.log('paused', video.paused);
}
}
<div><button onclick='start()'>Start</button></div>
无论如何,如果在某个时候将元素添加到DOM树并随后将其删除,则视频会自动暂停(!)
const video = document.createElement('video');
video.src = "https://upload.wikimedia.org/wikipedia/commons/transcoded/c/c6/Video_2017-03-19_23-01-33.webm/Video_2017-03-19_23-01-33.webm.480p.webm";
function start()
{
if (video.paused)
{
video.play().then(
() =>
setTimeout(
() =>
{
document.body.removeChild(video);
setTimeout(() => console.log('paused after', video.paused), 0);
},
3000
)
);
document.body.appendChild(video);
console.log('paused before', video.paused);
}
}
<div><button onclick='start()'>Start</button></div>
同样的考虑因素也适用于<audio>
元素。
我在这里有两个问题:
规范的哪一部分表示从DOM中删除视频元素后,它应该停止播放?
允许从DOM树中移除分离的视频但停止播放视频的理由是什么?这是令我最惊讶的部分。如果存在在页面上播放分离的视频的用例,那么为什么随后分离视频会停止播放?另一方面,如果由于没有理由继续播放而停止了分离的视频,那么为什么要首先让它开始分离呢?
答案 0 :(得分:1)
specification令人困惑。首先它说:
Media elements属于potentially playing而非in a document,不得播放任何视频,而应播放任何音频组件。媒体元素不能仅仅因为对它们的所有引用已被删除而停止播放;仅当媒体元素处于无法再播放该元素的状态时,该元素才可以被垃圾回收。
如果我正确理解这一点,则从DOM中删除该元素将停止视频,但音频应继续播放。
但是后来它说:
当媒体元素为removed from a Document时,用户代理必须运行以下步骤:
等待稳定状态,以允许继续执行从文档中删除媒体元素的任务。同步部分由该算法的所有其余步骤组成。 (同步部分中的步骤用marked标记。)
⌛如果media元素在文档中,请返回。
⌛运行media元素的内部暂停步骤。
第3步说暂停媒体。
步骤2似乎是多余的-如果将元素从文档中删除,该元素怎么能出现在文档中?但是步骤1可以将其添加回文档(或其他文档)中。这就是为什么它需要等待稳定状态的原因(这就是为什么您需要在示例中使用setTimeout()
的原因。
我认为第二个引号优先,因为当执行暂停步骤时,该元素不再“可能正在播放”。