使用Web组件创建自定义输入字段,而无需外部访问

时间:2019-02-26 17:32:59

标签: javascript web-component native-web-component

我想使用Shadow DOM创建自定义输入

class TextBox extends HTMLElement {

  constructor() {
    super();
    var shadow = this.attachShadow({ mode: 'open' });

    let textbox = document.createElement("input");
    shadow.appendChild(textbox);
    textbox.addEventListener("change", validate);

    function validate(event) {
      console.log("input can be validated");
    }
  }
  get value() {
    console.log("get");
    let textbox = this.shadowRoot.querySelector("input");
    return textbox.value;
  }
  set value(newValue) {
    console.log("set");
    let textbox = this.shadowRoot.querySelector("input");
    textbox.value = newValue;
  }
}
customElements.define('test-textbox', TextBox);

应该可以通过js更改显示的文本框的值。如果我更改文本框的.value属性,那么不会调用值的设置器吗?我想念什么吗?

稍后,我想通过模板将文本框包含在解决方案中,并能够通过textbox.value ="Peter"设置文本框的值

1 个答案:

答案 0 :(得分:0)

内部<input>字段每次其值更改时都会调度input事件。可以在您的组件中或使用组件的代码捕获此事件。

change事件仅在某些情况下发生,因此input事件是一个更好的选择。

下面的代码显示组件如何侦听input事件,外部代码也是如此。

function validate(event) {
  console.log("input can be validated");
}

class TextBox extends HTMLElement {
  constructor() {
    super();
    const shadow = this.attachShadow({ mode: 'open' });
    shadow.innerHTML = `
    <style>
      input {
        width: 300px;
      }
    </style>
    `;
    const textbox = document.createElement("input");
    shadow.appendChild(textbox);
    textbox.addEventListener("input", validate);
    textbox.focus();
  }

  get value() {
    console.log("get");
    let textbox = this.shadowRoot.querySelector("input");
    return textbox.value;
  }
  set value(newValue) {
    console.log("set");
    let textbox = this.shadowRoot.querySelector("input");
    textbox.value = newValue;
  }
}

customElements.define('test-textbox', TextBox);

const el = document.querySelector('test-textbox');
el.addEventListener("input", (evt) => {
  console.log('input event from the outside.');
});
<test-textbox></test-textbox>