JS自定义元素获取内部HTML

7 html javascript web-component shadow-dom

我们定义了这个自定义元素,如下所示......

<my-button>
   Submit
</my-button>
Run Code Online (Sandbox Code Playgroud)

和标准customElements定义

class MyButton extends HTMLElement{
   constructor(){
      super();
      // our custom code...
      this.innerHTML = ''; // ??? where did the 'Submit' go?
   }
}

...

customElements.define('my-button',MyButton);
Run Code Online (Sandbox Code Playgroud)

问题是,当尝试获取innerHTML时,我们知道我们可以做类似DOMContentLoaded或 的事情window.onload

但有时我们想使用代码动态创建“我的按钮”。并在附加时将其“渲染”...

有没有标准的方法来做到这一点?connectedcallback()它与其他“连接”功能有关系吗?

谢谢!

请注意 - 我已尝试使用connectedCallback()作为可能的解决方案,但这并不能解决问题。

Int*_*lia 3

有一组规则规定了在 Web 组件的构造函数中可以做什么和不能做什么。他们在下面。

\n

但想一想:

\n

可以通过以下三种方式之一创建组件:

\n
    \n
  1. 初始页面的一部分/使用innerHTML:当浏览器加载页面或使用时,innerHTML您可以将属性和子级添加到组件作为页面加载的一部分或innerHTML.
  2. \n
\n
parent.innerHTML = \'<super-hero name="Thor"><super-weapon value="Mjolnir"></super-weapon></super-hero>\'.\n
Run Code Online (Sandbox Code Playgroud)\n
    \n
  1. 您可以调用document.createELement来创建元素。在创建元素之前,您无法添加属性或子元素。
  2. \n
\n
let superHero = document.createElement(\'super-hero\');\nlet superWeapon = document.createElement(\'super-weapon\');\nsuperHero.setAttribute(\'name\', \'Thor\');\nsuperWeapon.setAttribute(\'value\',  \'Mjolnir\');\nsuperHero.appendChild(superWeapon);\nparent.appendChild(superHero)\n
Run Code Online (Sandbox Code Playgroud)\n
    \n
  1. 您可以使用实例化对象new。就像document.createElement必须等到元素创建后才能添加属性和子元素一样。
  2. \n
\n
let superHero = new SuperHero();\nlet superWeapon = new SuperWeapon();\nsuperHero.setAttribute(\'name\', \'Thor\');\nsuperWeapon.setAttribute(\'value\',  \'Mjolnir\');\nsuperHero.appendChild(superWeapon);\nparent.appendChild(superHero)\n
Run Code Online (Sandbox Code Playgroud)\n

创建组件后,它将添加到 DOM,此时您的组件connectedCallback将被调用。

\n

所有这三种方法实际上都可以归结为实例化newdocument.createElement调用CustomElementRegistry.get以获取该元素的构造函数,然后用于new创建对象。

\n

innerHTML解析 HTML,然后调用document.createElement或使用new来创建对象。

\n

但是,这样做时,当调用元素的构造函数时,没有属性或子元素。connectedCallback事实上,调用时可能没有任何子项或属性。这是在规范中添加observedAttributes和 的原因之一。attributeChangedCallback

\n

规范中缺少的一件事是知道有人在组件添加到 DOM 之前或之后添加或更改了子组件。但是,如果您确实想知道孩子何时发生变化,您可以使用MutationObserver.

\n

这就是构造函数中不存在子项或属性的原因。它们尚未添加。

\n

现在来说说规则:

\n
\n

在编写自定义元素构造函数时,作者必须遵守以下一致性要求:

\n
    \n
  • 对 super() 的无参数调用必须是构造函数主体中的第一个语句,以便在运行任何进一步的代码之前建立正确的原型链和该值。

    \n
  • \n
  • return 语句不得出现在构造函数体内的任何位置,除非它是简单的早期返回(return 或 return this)。

    \n
  • \n
  • 构造函数不得使用 document.write() 或 document.open() 方法。

    \n
  • \n
  • 不得检查元素的属性和子元素,因为在非升级情况下不会出现任何属性和子元素,并且依赖升级会降低元素的可用性。

    \n
  • \n
  • 该元素不得获得任何属性或子元素,因为这违反了使用 createElement 或 createElementNS 方法的使用者的期望。

    \n
  • \n
  • 一般来说,工作应该尽可能推迟到connectedCallback\xe2\x80\x94,尤其是涉及获取资源或渲染的工作。但是,请注意,connectedCallback 可以被多次调用,因此任何真正一次性的初始化工作都需要一个防护来防止它运行两次。

    \n
  • \n
  • 一般来说,构造函数应该用于设置初始状态和默认值,并设置事件侦听器和可能的影子根。

    \n
  • \n
\n

其中一些要求会在元素创建过程中直接或间接进行检查,如果不遵循这些要求,将导致自定义元素无法由解析器或 DOM API 实例化。

\n
\n