Создать пользовательский элемент ввода - PullRequest
10 голосов
/ 06 мая 2019

Я пытаюсь создать пользовательский компонент, который расширяет компонент HTMLInputElement, но ничего не рендерится.

class myInput extends HTMLInputElement {};

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

Что мне здесь не хватает?

1 Ответ

23 голосов
/ 06 мая 2019

То, что вы ожидаете, не происходит, потому что это неправильный способ расширения уже встроенного элемента.

Как говорится в документации 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',
});
<input type="text" placeholder="simple input">
<input is="spot-input" type="text" placeholder="spot input">

Но я предполагаю, что вам нужно разрешить использовать тег <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);
<input type="number">
<spot-input type="number"></spot-input>

Тогда, если вы проверите дерево DOM, вы должны иметь:

<input type="number">

<spot-input type="number">
    #shadow-root (open)
        <input type="number">
</spot-input>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...