【问题标题】:Adding element to youtube向 youtube 添加元素
【发布时间】:2021-09-28 02:16:23
【问题描述】:

我正在尝试将此自定义元素添加到 YouTube。

一开始我是在控制台写的:

const script1 = document.createElement("script")
script1.type = "module"
script1.src = "https://unpkg.com/pose-viewer@0.0.4/dist/pose-viewer/pose-viewer.esm.js"
document.head.appendChild(script1)

然后:

document.createElement('pose-viewer')

但我收到了这个错误:

Uncaught TypeError: Class constructor a cannot be invoked without '新的' 在新 g (custom-elements-es5-adapter.js:11) 在:1:10

所以我编译成es5:

const script1 = document.createElement("script")
script1.src = "https://unpkg.com/pose-viewer@0.1.2/dist/pose-viewer/pose-viewer.js"
document.head.appendChild(script1)

但我收到了这个错误:

未捕获的类型错误:非法调用 在 n.f (pose-viewer.js:15) 在 Function.getOwnPropertyDescriptor (pose-viewer.js:15) 在pose-viewer.js:44 在pose-viewer.js:58 在pose-viewer.js:130

我做错了什么?为什么这不适用于 YouTube,但在其他任何地方都可以使用?

【问题讨论】:

  • 我假设您尝试从unpkg.com 添加的脚本不是您编写的?您能否提供有关该脚本的更多信息?
  • @Philipp 脚本是我写的。它是一个用 Stencil 编写的名为 pose-viewer 的自定义元素(Web 组件)。
  • 好吧,那么错误似乎在您自己的脚本中。您是否尝试上传非缩小版本并对其进行调试?
  • 脚本在其他网站上运行得很好,就像 OP 说的那样,而不是在 YouTube 上。从进一步的调试来看,YouTube 似乎正在使用某种脚本 custom-elements-es5-adapter,它会弄乱正确的自定义元素,
  • 看起来像是 Polymer 中使用的 polyfill:polymer-library.polymer-project.org/2.0/docs/polyfills

标签: javascript youtube custom-element stenciljs


【解决方案1】:

如果您查看https://unpkg.com/pose-viewer@0.1.2/dist/pose-viewer/pose-viewer.js 的源代码,您会看到它已被转译为 ES5,但是自定义元素应在 ES6 中定义,例如:

class MyElement extends HtmlElement {}

更多关于适配器的信息在这里:

https://www.npmjs.com/package/@webcomponents/webcomponentsjs#custom-elements-es5-adapterjs

您只需要在运行脚本之前按照错误消息并将其添加到您的 html 中即可:

<script src="https://unpkg.com/@webcomponents/webcomponentsjs@2.5.0/custom-elements-es5-adapter.js"></script>

更新

如果您使用的是 esm 脚本,则不需要适配器,因为该脚本使用的是 es6 语法。

您可以将脚本作为模块加载:

<!DOCTYPE html>
 <html>
<head>
      <meta charset="utf-8">
      <meta name="viewport" content="width=device-width">
      <title>pose viewer example</title>
</head>
<body>
<script src="https://unpkg.com/pose-viewer@latest/dist/pose-viewer/pose-viewer.esm.js" type="module"></script>
<pose-viewer></pose-viewer>
</body>
</html>

或者如果你想从另一个 js 脚本中导入它,你只需要添加一个 import 语句

html 可能如下所示:

<!DOCTYPE html>
 <html>
<head>
      <meta charset="utf-8">
      <meta name="viewport" content="width=device-width">
      <title>pose viewer example</title>
</head>
<body>
<script src="./index.js" type="module"></script>
</body>
</html>

还有这样的脚本:

  import "https://unpkg.com/pose-viewer@latest/dist/pose-viewer/pose-viewer.esm.js";
 const x = document.createElement('pose-viewer');
 document.body.appendChild(x);

更新

要通过控制台将其加载到 youtube 网站,您需要使用 new 运算符,使用 esm 模块,加载部分如下所示

 const script = document.createElement('script')
 script.setAttribute('type', 'module');
 script.setAttribute('src', 'https://unpkg.com/pose-viewer@0.0.4/dist/pose-viewer/pose-viewer.esm.js' );
 document.body.appendChild(script);

然后从 customElement 注册表中获取类并使用new 调用它:

 const PoseViewer = customElements.get('pose-viewer');
 new PoseViewer();

【讨论】:

  • 谢谢。当包含带有esm 的es6 包时,在attachShadow 调用中会收到“非法调用”。但是,它适用于不包括该适配器的任何其他网站。
  • 这里需要注意的是这个适配器不需要转译,脚本必须按原样加载到页面中。在我们的公司项目中,我们仍然使用从 typescript 转译的 es5 包。我将脚本添加到包中,它可以正常工作
  • 我不确定我是否理解 - 抱歉。我添加了你在加载之前记下的 unpkg 脚本,并尝试加载转译后的 es5 pose-viewerpose-viewer 的原始 esm 版本,但都失败了,我不确定你建议我们应该做什么。
  • 你想让它在哪个浏览器中工作?
  • 现在我明白了你的问题,我已经更新了我的答案
猜你喜欢
  • 1970-01-01
  • 2020-04-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多