创建一个自定义输入元素

dut*_*tzi 10 html javascript custom-element

我正在尝试创建一个自定义组件来扩展该HTMLInputElement组件,但不会呈现任何内容。

class myInput extends HTMLInputElement {};

customElements.define('my-input', myInput, {
  extends: 'input'
});
Run Code Online (Sandbox Code Playgroud)
<my-input type="text"></my-input>
Run Code Online (Sandbox Code Playgroud)

我在这里想念什么?

Kév*_*let 24

您期望的结果不会发生,因为这不是扩展已内置元素的正确方法。

如MDN文档所述,您需要将内置标记保留在DOM中并使其成为is属性。

通过关注现场输入来查看下面的代码片段。

class spotInput extends HTMLInputElement {
  constructor(...args) {
    super(...args);
    
    this.addEventListener('focus', () => {
      console.log('Focus on spotinput');
    });
  }
};

customElements.define('spot-input', spotInput, {
  extends: 'input',
});
Run Code Online (Sandbox Code Playgroud)
<input type="text" placeholder="simple input">
<input is="spot-input" type="text" placeholder="spot input">
Run Code Online (Sandbox Code Playgroud)

但是我猜想您想被允许使用<spot-input>标签。您可以通过附加一个影子DOM,创建一个自主元素并将其附加到来做到这一点<input>

class spotInput extends HTMLElement {
  constructor(...args) {
    super(...args);
    
    // Attaches a shadow root to your custom element.
    const shadowRoot = this.attachShadow({mode: 'open'});
    
    // Defines the "real" input element.
    let inputElement = document.createElement('input');
    inputElement.setAttribute('type', this.getAttribute('type'));
    
    inputElement.addEventListener('focus', () => {
      console.log('focus on spot input');
    });
    
    // Appends the input into the shadow root.
    shadowRoot.appendChild(inputElement);
  }
};

customElements.define('spot-input', spotInput);
Run Code Online (Sandbox Code Playgroud)
<input type="number">
<spot-input type="number"></spot-input>
Run Code Online (Sandbox Code Playgroud)

然后,如果您检查DOM树,则应该具有:

<input type="number">

<spot-input type="number">
    #shadow-root (open)
        <input type="number">
</spot-input>
Run Code Online (Sandbox Code Playgroud)