为什么<video>从DOM中删除后会停止播放,而仍然可以分离播放?

时间:2018-06-19 21:13:34

标签: javascript html5 dom html5-video

我正在研究一个自定义组件,偶然发现了这种奇怪的行为。基本上,可以完全不向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>元素。

我在这里有两个问题:

  1. 规范的哪一部分表示从DOM中删除视频元素后,它应该停止播放?

  2. 允许从DOM树中移除分离的视频但停止播放视频的理由是什么?这是令我最惊讶的部分。如果存在在页面上播放分离的视频的用例,那么为什么随后分离视频会停止播放?另一方面,如果由于没有理由继续播放而停止了分离的视频,那么为什么要首先让它开始分离呢?

1 个答案:

答案 0 :(得分:1)

specification令人困惑。首先它说:

  

Media elements属于potentially playing而非in a document,不得播放任何视频,而应播放任何音频组件。媒体元素不能仅仅因为对它们的所有引用已被删除而停止播放;仅当媒体元素处于无法再播放该元素的状态时,该元素才可以被垃圾回收。

如果我正确理解这一点,则从DOM中删除该元素将停止视频,但音频应继续播放。

但是后来它说:

  

当媒体元素为removed from a Document时,用户代理必须运行以下步骤:

     
      
  1. 等待稳定状态,以允许继续执行从文档中删除媒体元素的任务。同步部分由该算法的所有其余步骤组成。 (同步部分中的步骤用marked标记。)

  2.   
  3. ⌛如果media元素在文档中,请返回。

  4.   
  5. ⌛运行media元素的内部暂停步骤。

  6.   

第3步说暂停媒体。

步骤2似乎是多余的-如果将元素从文档中删除,该元素怎么能出现在文档中?但是步骤1可以将其添加回文档(或其他文档)中。这就是为什么它需要等待稳定状态的原因(这就是为什么您需要在示例中使用setTimeout()的原因。

我认为第二个引号优先,因为当执行暂停步骤时,该元素不再“可能正在播放”。