繁体   English   中英

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

[英]How can I create a web component that acts like a form element?

我正在尝试创建一个特定于表单元素中可用的Web组件,它具有namevalue 我意识到我可以创建一个extends HTMLInputElement的Web组件:

<input is="very-extended">

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

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

如果你看一下常规输入字段的阴影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() ) 
 <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> 

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

KevBot,

您似乎认为元素包含在表单中。 事实并非如此。 它是通过标记名称搜索其子元素的表单,以决定它应包含哪些元素。 它将简单地忽略具有未知标签名称的那些。

您的custom-input名称不在表单搜索的元素中。 因此,它不包含在表格中。 自定义元素的原型并不重要。 这就是为什么它可以使用is ,从那时起,标签名称被维护。

当然,如果需要,您可以实现自己的custom-form ,其行为方式不同。

您可以创建将由form解释的<custom-input>自定义元素,只需在template内添加一个隐藏的 input元素,其中包含您想要的namevalue对。

<template>
    <input type="hidden" name="foo" value="defaultVal">
</template>

默认value (和name )可以由您的自定义元素内部逻辑更新。

此隐藏input 不得插入Shadow DOM中以供容器form检测。

 (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() ) 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <template id="test"> <input type="hidden" name="foo" value="bar"> </template> <form> <input name="regular" value="input"> <custom-input name="foo" value="bar"></custom-input> </form> 

你可以这样做:

 (function() { var newInputExtended = Object.create(HTMLInputElement.prototype); newInputExtended.createdCallback = function() { this.value = 'baz'; }; document.registerElement('foo-input', { extends: 'input', prototype: newInputExtended }); window.something = function(form, event) { $('<p>') .text($(form).serialize()) .appendTo('body') event.preventDefault(); } })(); 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <form onsubmit="something(this, event)"> <input is="foo-input" name="foo" value="bar"> <button>Hi</button> </form> 

但是如果您尝试创建新的影子根,则会出现错误。 看起来您只能在元素的用户代理阴影根周围扩展数据/逻辑。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM