使用 DOMParser 时 <video> 标签在 Safari 中不起作用

Lim*_*nte 5 javascript safari webkit html5-video domparser

使用 时DOMParser,<video>标签在 Safari 中不起作用,其预览会呈现,但没有控件且无法播放:

const parser = new DOMParser()
const parsed = parser.parseFromString(
  document.querySelector('video').outerHTML, 
  'text/html'
)
document.body.appendChild(parsed.querySelector('body').childNodes[0])
Run Code Online (Sandbox Code Playgroud)
<video
  width="250"
  controls
  playsinline
  src="https://interactive-examples.mdn.mozilla.net/media/cc0-videos/flower.mp4#t=0.001"
></video>
Run Code Online (Sandbox Code Playgroud)

上面的代码在 Chrome 中按预期工作:

在此输入图像描述

但 Safari 会呈现这个(macOS 和 iOS):

在此输入图像描述

没有控件,无法播放 DOMParser 生成的第二个视频。

这是某种安全功能还是错误?这种行为有什么解决方法吗?

sta*_*all 3

这是一个错误

这是 webkit 错误单的链接。

  • 评论#6(2021-03-04 22:50:29 PST):

    [...] 媒体元素在没有浏览上下文的文档中创建时不会初始化其 UA 影子根。修复方法是在将媒体元素控件插入具有浏览上下文的文档后对其进行初始化。

  • 评论#12(2022-08-02 11:16:50 PDT):拉取请求:https://github.com/WebKit/WebKit/pull/2955

  • 评论#13(2022-08-08 11:47:08 PDT):已提交253225@main (f331cc98c1de): https: //commits.webkit.org/253225@main已审核的提交已落地。关闭 PR #2955 并删除活动标签。

这是一个解决方法

// keep doing what you were doing:
const parser = new DOMParser()
const parsed = parser.parseFromString(
  document.querySelector('video').outerHTML, 
  'text/html'
);
const child = document.body.appendChild(parsed.querySelector('body').childNodes[0]);

// but then force the media elements to reload afterward:
[child].concat(Array.from(child.querySelectorAll("video, audio")))
  .forEach(e => e.outerHTML = e.outerHTML);
Run Code Online (Sandbox Code Playgroud)

还有其他解决方法,例如cloneNode@Tibic4 建议的方法,但我认为这个方法很好,因为您仍然可以继续使用DOMParser大部分工作。

一旦部署了 webkit 修复程序,您将不再需要应用该修复程序的任何 Safari 版本的解决方法。希望它能得到合理的向后移植。