如何让表单提交自定义 HTML 元素的 Shadow root 内的输入值?

Mic*_*sai 6 html javascript

我创建了一个自定义 HTML 输入元素,如下所示:

<html>
<script>
    class TestInput extends HTMLElement {
      constructor() {
        super();
        var shadow = this.attachShadow({mode:'open'});
        var cinput = document.createElement('input');
        cinput.setAttribute('type', 'text');
        cinput.setAttribute('name', 'test');
        cinput.setAttribute('value', 'test');
        shadow.append(cinput);
        this.cinput = cinput;

        }
    }
customElements.define('test-input', TestInput);
</script>
<body>
<form action="/test">
  <test-input></test-input>
  <input type="submit"></input>
</form>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)

但是,当我使用spring接收表单参数时,我什么也没得到。如何提交带有影子根内输入值的表单?

Jos*_*ose 3

根据@nick-parsons评论中链接的web.dev/more-capable-form-controls


首先,您需要将formAssociatedstatic 属性添加到自定义元素的类中并对其进行分配,true以便将自定义元素转换为与表单相关的自定义元素,如下所示:

class MyCustomElem extends HTMLElement {
  static formAssociated = true;
  //...
}
Run Code Online (Sandbox Code Playgroud)

然后你想在你的自定义元素上调用HTMLElement.attachInternals()

constructor()可以这样做

let internals = this.attachInternals()

为了使用从返回的ElementInternals.setFormValue()attachInternals()

最后,您将使用setFormValue()更新自定义元素将提交到外部表单的值,可能通过addEventListener().


修改问题中的示例:

<html>
<script>
    class TestInput extends HTMLElement {

      // make element form-associated
      static formAssociated = true;

      constructor() {
        super();
        var shadow = this.attachShadow({mode:'open'});
        var cinput = document.createElement('input');
        cinput.setAttribute('type', 'text');
        cinput.setAttribute('name', 'test');
        cinput.setAttribute('value', 'test');
        shadow.append(cinput);
        this.cinput = cinput;

        // get form-related abilities
        this.internals = this.attachInternals();
        this.cinput.addEventListener("input",
          (event) => {
            let value = event.textContent
            // update value that form has access to
            this.internals.setFormValue(value)
          })

        }
    }
customElements.define('test-input', TestInput);
</script>
<body>
<form action="/test">
  <test-input></test-input>
  <input type="submit"></input>
</form>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)