简体   繁体   English

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

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

I am trying to create a web component that is usable in a form element specifically, that has a name , and a value . 我正在尝试创建一个特定于表单元素中可用的Web组件,它具有namevalue I recognize that I can create a web component that extends an HTMLInputElement : 我意识到我可以创建一个extends HTMLInputElement的Web组件:

<input is="very-extended">

but I am trying to create an entirely new element. 但我正在努力创造一个全新的元素。

When creating a regular web component, you can create it from the prototype of a regular HTMLElement ( HTMLElement.prototype ). 创建常规Web组件时,可以从常规HTMLElementHTMLElement.prototype )的原型创建它。 Which leads me to assume that I can create a different element with the prototype of an HTMLInputElement ( HTMLInputElement.prototype ). 这让我想到我可以使用HTMLInputElementHTMLInputElement.prototype )的原型创建一个不同的元素。 You actually use that prototype when extending the API of input elements, so why can't I use that prototype to create an entirely new element that works in a form? extending输入元素的API时extending您实际上是使用该原型,那么为什么我不能使用该原型来创建一个在表单中工作的全新元素?

If you look at the shadow dom of a regular input field: 如果你看一下常规输入字段的阴影dom:

在此输入图像描述

you can see that there is a div inside of there. 你可以看到里面有一个div。 I understand that this HTMLInputElement has methods and attributes, getters/setters, etc. So why is it that when I attempt to create my component, it fails to be part of the name, value pairs found in the form? 我知道这个HTMLInputElement有方法和属性,getter / setter等等。那么为什么当我尝试创建我的组件时,它不能成为表单中找到的名称,值对的一部分?

Here is an example of how I am trying to create this web component: 以下是我尝试创建此Web组件的示例:

Please note that his should be tested in a browser that supports web components. 请注意,他应该在支持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> 

Why is the name, value pair not found among the form, and how can I create a custom form element? 为什么在表单中找不到名称,值对,以及如何创建自定义表单元素?

KevBot, KevBot,

You seem to think that the element includes itself in the form. 您似乎认为元素包含在表单中。 That is not the case. 事实并非如此。 It is the form that searches its children elements by tag name , to decide which elements it should include. 它是通过标记名称搜索其子元素的表单,以决定它应包含哪些元素。 It will simply ignore those with unknown tag names. 它将简单地忽略具有未知标签名称的那些。

Your custom-input name is not among the elements the form searches. 您的custom-input名称不在表单搜索的元素中。 Therefore, it is not included on the form. 因此,它不包含在表格中。 It doesn't matter the custom element's prototype. 自定义元素的原型并不重要。 That's why it works if you use is , since then the tag name is maintained. 这就是为什么它可以使用is ,从那时起,标签名称被维护。

Of course, you may implement your own custom-form that behaves differently, if you want. 当然,如果需要,您可以实现自己的custom-form ,其行为方式不同。

You can create your <custom-input> custom element that will be interpreted by a form , just by adding inside your template a hidden input element with the name and value pair your want. 您可以创建将由form解释的<custom-input>自定义元素,只需在template内添加一个隐藏的 input元素,其中包含您想要的namevalue对。

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

The default value (and name ) can by updated by your custom element internal logic. 默认value (和name )可以由您的自定义元素内部逻辑更新。

This hidden input must not be inserted inside a Shadow DOM to be detected by the container form . 此隐藏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> 

You can do this: 你可以这样做:

 (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> 

But you get an error if you try to create a new shadow root. 但是如果您尝试创建新的影子根,则会出现错误。 It looks like you are limited to only extending the data/logic around the element's user-agent shadow root. 看起来您只能在元素的用户代理阴影根周围扩展数据/逻辑。

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

相关问题 如何在 Typescript 中制作一个像真正的“if”一样的 React“If”组件? - How can I make a React "If" component that acts like a real "if" in Typescript? 如何创建一个像水平滚动条一样的按钮? - How can I create a button that acts like a horizontal scroll bar? 我如何创建这样的表格? - how can i create a form like this? Bootstrap 4:我如何创建这样的表单? - Bootstrap 4 : How can I create a form like this? 如何使用CSS和JS创建网页,使其像UITabBar(框架?) - How to create a web page with CSS and JS so it acts like UITabBar (framework?) 如何为表单元素制作 controller 组件 - How can i make controller component for Form Element 如何在 Web 组件中创建手风琴自定义元素 - How to create Accordion custom element in web component 如何在Titanium Mobile上创建类似于表格视图的选择器? - How do I create a picker that acts like a table view on Titanium Mobile? 我怎样才能制作一个像 jQuery 的 slideUp() 一样的 function,但是对于向上以外的方向? - How can I make a function that acts like jQuery's slideUp(), but for directions other than up? Javascript:如何创建既像对象又像函数的变量? - Javascript: How to create a variable that acts like both an object and a function?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM