我正在尝试创建一个可在表单元素中使用的Web组件,该组件具有name
和value
。我意识到我可以创建extends
和HTMLInputElement
:
<input is="very-extended">
但我正在尝试创建一个全新的元素。
创建常规Web组件时,您可以从常规HTMLElement
(HTMLElement.prototype
)的原型创建它。这让我认为我可以使用HTMLInputElement
(HTMLInputElement.prototype
)的原型创建不同的元素。实际上在extending
输入元素的API时使用该原型,为什么我不能使用该原型来创建一个在表单中工作的全新元素?
如果你看一下常规输入字段的阴影dom:
你可以看到里面有一个div。我知道这个HTMLInputElement
有方法和属性,getter / setter等等。那么为什么当我尝试创建我的组件时,它不能成为表单中找到的名称,值对的一部分? / p>
以下是我尝试创建此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>
为什么在表单中找不到名称,值对,以及如何创建自定义表单元素?
答案 0 :(得分:3)
KevBot,
您似乎认为元素包含在表单中。事实并非如此。它是通过标记名称搜索其子元素的表单,以决定它应包含哪些元素。它将简单地忽略具有未知标签名称的那些。
您的custom-input
名称不在表单搜索的元素中。因此,它不包含在表格中。自定义元素的原型并不重要。这就是为什么如果你使用is
它的原因,那么标签名称就会被维护。
当然,如果需要,您可以实现自己的行为custom-form
。
答案 1 :(得分:3)
您可以创建由<custom-input>
解释的form
自定义元素,只需在template
隐藏 input
中添加内容即可元素与
name
和value
配对您的需求。
<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>
答案 2 :(得分:2)
你可以这样做:
(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();
}
})();
&#13;
<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>
&#13;
但是如果您尝试创建新的影子根,则会出现错误。看起来您只能在元素的用户代理阴影根周围扩展数据/逻辑。