如何创建一个像表单元素一样的Web组件?

Kev*_*Bot 8 javascript forms web-component html5-template custom-element

我正在尝试创建一个特定于表单元素中可用的Web组件,它具有a name和a value.我承认,我可以创建一个Web组件,它extendsHTMLInputElement:

<input is="very-extended">
Run Code Online (Sandbox Code Playgroud)

但我正在努力创造一个全新的元素.

创建常规Web组件时,可以从regular HTMLElement(HTMLElement.prototype)的原型创建它.这让我想到我可以用HTMLInputElement(HTMLInputElement.prototype)的原型创建一个不同的元素.您实际上extending在输入元素的API 时使用该原型,那么为什么我不能使用该原型来创建一个在表单中工作的全新元素?

如果你看一下常规输入字段的阴影dom:

在此输入图像描述

你可以看到里面有一个div.我知道这HTMLInputElement有方法和属性,getter/setter等等.那么为什么当我尝试创建我的组件时,它不能成为表单中找到的名称,值对的一部分?

以下是我尝试创建此Web组件的示例:

请注意,他应该在支持Web组件的浏览器中进行测试.

(function() {

  var iconDoc = (document._currentScript || document.currentScript).ownerDocument;
  var objectPrototype = Object.create(HTMLInputElement.prototype);

  Object.defineProperty(objectPrototype, 'name', {
    writable: true
  });

  Object.defineProperty(objectPrototype, 'value', {
    writable: true
  });

  objectPrototype.createdCallback = function() {
    var shadow = this.createShadowRoot();
    var template = iconDoc.querySelector('#test');
    shadow.appendChild(template.content.cloneNode(true));
  };

  document.registerElement('custom-input', {
    prototype: objectPrototype
  });

})();

console.log(
  $('form').serialize()
)
Run Code Online (Sandbox Code Playgroud)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<template id="test">
  <div>This is a special input</div>
</template>

<form>
  <input name="regular" value="input">
  <custom-input name="foo" value="bar"></custom-input>
</form>
Run Code Online (Sandbox Code Playgroud)

为什么在表单中找不到名称,值对,以及如何创建自定义表单元素?

Sup*_*arp 5

您可以创建<custom-input>将由 a 解释的自定义元素form,只需在隐藏元素中添加template与您 想要 的和配对即可。inputnamevalue

<template>
    <input type="hidden" name="foo" value="defaultVal">
</template>
Run Code Online (Sandbox Code Playgroud)

默认值value(和name)可以通过您的自定义元素内部逻辑进行更新。

此隐藏input 不得插入 Shadow DOM 内以被容器检测到form

<template>
    <input type="hidden" name="foo" value="defaultVal">
</template>
Run Code Online (Sandbox Code Playgroud)
(function() {

  var iconDoc = (document._currentScript || document.currentScript).ownerDocument;
  var objectPrototype = Object.create(HTMLInputElement.prototype);

  objectPrototype.createdCallback = function() {
    //var shadow = this.createShadowRoot();
    var template = iconDoc.querySelector('#test');
    this.appendChild(template.content.cloneNode(true));
  };

  document.registerElement('custom-input', {
    prototype: objectPrototype
  });

})();

console.log(
  $('form').serialize()
)
Run Code Online (Sandbox Code Playgroud)