使用 Web 组件创建没有外部可访问性的自定义输入字段

Creating a custom input field with Web Components without outside accessability

我想用 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 属性 值的 setter 不会被调用?我错过了什么吗?

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

设置文本框的值

内部 <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>