文档片段内自定义元素的初始化

und*_*ned 5 html javascript documentfragment custom-element html-templates

考虑这个template带有两个 flatx-element和一个嵌套的HTML 。

<template id="fooTemplate">
  <x-element>Enter your text node here.</x-element>
  <x-element>
    <x-element>Hello, World?</x-element>
  </x-element>
</template>
Run Code Online (Sandbox Code Playgroud)

如何初始化(触发构造函数)从fooTemplate文档片段克隆的所有自定义元素而不将其附加到 DOM,也不是通过使用is="x-element";扩展内置元素;要么是整个片段。

class XElement extends HTMLElement {
  constructor() { super(); }
  foo() { console.log( this ); }
} customElements.define( 'x-element', XElement );

const uselessf = function( temp ) {
  const frag = window[ temp ].content.cloneNode( true );

  /* Your magic code goes here:
  */ do_black_magic( frag );

  for (const e of  frag.querySelectorAll('x-element') )
    e.foo(); // This should work.

  return frag;
};

window['someNode'].appendChild( uselessf('fooTemplate') );
Run Code Online (Sandbox Code Playgroud)

请注意,脚本使用defer属性执行。

und*_*ned 3

我们可以用这个箭头函数初始化模板:

const initTemplate = temp =>
  document.createRange().createContextualFragment( temp.innerHTML );

const frag = initTemplate( window['someTemplate'] );
Run Code Online (Sandbox Code Playgroud)

或者使用原型上定义的方法template(我更喜欢这种方式):

Object.defineProperty(HTMLTemplateElement.prototype, 'initialise', {
  enumerable: false,
  value() {
    return document.createRange().createContextualFragment( this.innerHTML );
  }
});

const frag = window['someTemplate'].initialise();
Run Code Online (Sandbox Code Playgroud)

无论如何,这段代码都能正常工作:

for (const elem of  frag.querySelectorAll('x-element') )
  elem.foo();

window['someNode'].appendChild( frag );
Run Code Online (Sandbox Code Playgroud)

我不确定这些方法是否是初始化模板中自定义元素的最有效方法。

另请注意,不需要克隆模板。