我尝试通过Web组件创建自定义文本框
'use strict';
class TextBox extends HTMLElement {
constructor() {
super();
var shadow = this.attachShadow({ mode: 'open' });
let textbox = document.createElement("input");
shadow.appendChild(textbox);
textbox.addEventListener("change", this.validate);
textbox.value ="Init";
}
validate(event) {
console.log("input can be validated");
}
get value() {
console.log("get");
let textbox = this.shadowRoot.querySelector("input");
return textbox.value;
}
set value(newValue) {
console.log("set");
let textbox = this.shadowRoot.querySelector("input");
textbox.value = newValue;
}
}
customElements.define('test-textbox',TextBox);
稍后,我想将自定义输入嵌入模板中并在添加前更改其值:
let control= document.getElementById("control");
let clone = control.content.cloneNode(true);
clone.children[0].value = "tb value has been changed before adding";
document.getElementById("app").appendChild(clone);
但是,如果在我的代码中执行此操作,则输入的值将保留在“ Init”上,但是我的自定义控件的值将具有“ tb值已在添加前更改”属性。
从HTMLInput扩展会更好吗? 设置例程也只会触发一次。
答案 0 :(得分:0)
值是输入的属性,而不是属性。要设置HTML元素的属性,您必须使用textbox.setAttribute('value', myNewValue)
答案 1 :(得分:0)
您不需要扩展HTMLInput。这就是我要做的。我将传递给<text-box />
的所有属性添加到其内部输入元素中,但是除非您试图更紧密地模仿输入元素,否则没有必要。
我希望扩展像HTMLInput这样的特定元素不会很快成为问题,但是我倾向于避免使用它们,因为moment上存在一些问题。
const css = `
<style>
:host([hidden]) { display: none; }
:host {
display: block;
}
input {
background-color: #f5f5f5;
border: 1px solid transparent;
border-radius: 4px;
padding: 1em;
font-size: 16px;
width: 400px;
}
input:focus {
background-color: #fff;
border: 1px solid #dadce0;
outline: 0;
}
</style>
`
const html = `<input type='text' value='Init' />`
class TextBox extends HTMLElement {
static get observedAttributes () {
return ['value']
}
constructor () {
super()
this.attachShadow({mode: 'open'})
this.shadowRoot.appendChild(template.content.cloneNode(true))
// Cache the value of the inputNode
this.inputNode = this.shadowRoot.querySelector('input')
this.inputNode.value = 'Something else'
// Add all properties on text-box to input
for (let i = 0; i < this.attributes.length; i++) {
this.inputNode.setAttribute(
this.attributes[i].nodeName,
this.attributes[i].nodeValue
)
}
}
validate (event) {
console.log('input can be validated')
}
get value () {
return this.inputNode.value
}
set value (newValue) {
this.inputNode.value = newValue
}
connectedCallback () {
this.inputNode.addEventListener('change', this.validate)
}
disconnectedCallback () {
this.inputNode.removeEventListener('change', this.validate)
}
attributeChangedCallback (name, oldValue, newValue) {
if (name === 'value') {
this.inputNode.value = newValue
}
}
}
const template = document.createElement('template')
template.innerHTML = `${css}${html}`
window.customElements.define('text-box', TextBox)