Shadow DOM 中的属性不会改变
Attribute doesnt change inside ShadowDOM
在我的以下代码中,值的更改不会更新输入值:为什么?
class textfield extends HTMLElement {
get value()
{
return this.getAttribute("value");
}
set value(val)
{
this.setAttribute('value', val);
}
get readonly() {
return this.hasAttribute("readonly");
}
set readonly(val)
{
if (val)
{
this.setAttribute("readonly", '');
}
else
{
this.removeAttribute("readonly");
}
}
static get observedAttributes() {
return ['readonly', 'value'];
}
attributeChangedCallback(name, oldValue, newValue) {
console.log(name, newValue) ;
}
constructor()
{
super();
this.attachShadow({ "mode": "open" });
}
connectedCallback()
{
this.shadowRoot.innerHTML =
/*html*/`
<div>
<div>
Lable
</div>
<div>
<input id="vi-input" type="text" value="${this.getAttribute("value")}" ${ this.hasAttribute("readonly") ? "readonly" : "" } />
</div>
<div>
<span>Error</span>
</div>
</div>
`;
}
}
window.customElements.define("vi-textfield", textfield);
在我的 index.html 中:
....
<vi-textfield id="myInput" value="2" validation="^\d{4}$" ></vi-textfield>
....
当我通过 JS 更新它时,让我们说:
document.getElementById("myInput").value = 3;
会有给定的 console.log attributeChangedCallback 但值本身不会改变....
我猜你正在设置值,但之后没有做任何事情,至少没有对输入字段做任何事情。如果你使用你的元素选项卡查看你的元素 vi-textfield
实际上是更新了浏览器的开发者工具。例如,您可以通过调用
设置值后重建 html
this.connectedCallback();
确保输入字段也包含更新后的值。
或者你需要想办法 select 并单独更新输入字段。或者只是回忆一下我提到的 connectedCallback()
方法。
或者您可以将某种 MutationObserver 添加到您的 class (https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver),但我不认为这应该像您想象的那样开箱即用:在更新主机值,更新影子元素。
您的 input
没有更新,因为它们是 2 个不同的元素。
set value(val) {
this.setAttribute('value', val);
}
将 value
属性设置为
<vi-textfield value="[val]">
不是
上的 value
属性
<input id="vi-input" type="text" value="${this.getAttribute("value")}"/>
这是您的元素 shadowDOM 中的另一个 元素
value="${this.getAttribute("value")}"
运行 一次,因为 connectedCallback()
运行 一次
如果你想同时设置,你可以这样做:
set value(val) {
this.setAttribute('value', val);
this.shadowRoot.getElementById("vi-input").setAttribute("value", val);
}
如果你想让它们同步,你还需要 setAttribute 代码用于 value
输入变化时。
PS.
set readonly(val) {
if (val) {
this.setAttribute("readonly", '');
} else {
this.removeAttribute("readonly");
}
}
可以写成:
set readonly(val) {
this.toggleAttribute("readonly", val);
}
在我的以下代码中,值的更改不会更新输入值:为什么?
class textfield extends HTMLElement {
get value()
{
return this.getAttribute("value");
}
set value(val)
{
this.setAttribute('value', val);
}
get readonly() {
return this.hasAttribute("readonly");
}
set readonly(val)
{
if (val)
{
this.setAttribute("readonly", '');
}
else
{
this.removeAttribute("readonly");
}
}
static get observedAttributes() {
return ['readonly', 'value'];
}
attributeChangedCallback(name, oldValue, newValue) {
console.log(name, newValue) ;
}
constructor()
{
super();
this.attachShadow({ "mode": "open" });
}
connectedCallback()
{
this.shadowRoot.innerHTML =
/*html*/`
<div>
<div>
Lable
</div>
<div>
<input id="vi-input" type="text" value="${this.getAttribute("value")}" ${ this.hasAttribute("readonly") ? "readonly" : "" } />
</div>
<div>
<span>Error</span>
</div>
</div>
`;
}
}
window.customElements.define("vi-textfield", textfield);
在我的 index.html 中:
....
<vi-textfield id="myInput" value="2" validation="^\d{4}$" ></vi-textfield>
....
当我通过 JS 更新它时,让我们说:
document.getElementById("myInput").value = 3;
会有给定的 console.log attributeChangedCallback 但值本身不会改变....
我猜你正在设置值,但之后没有做任何事情,至少没有对输入字段做任何事情。如果你使用你的元素选项卡查看你的元素 vi-textfield
实际上是更新了浏览器的开发者工具。例如,您可以通过调用
this.connectedCallback();
确保输入字段也包含更新后的值。
或者你需要想办法 select 并单独更新输入字段。或者只是回忆一下我提到的 connectedCallback()
方法。
或者您可以将某种 MutationObserver 添加到您的 class (https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver),但我不认为这应该像您想象的那样开箱即用:在更新主机值,更新影子元素。
您的 input
没有更新,因为它们是 2 个不同的元素。
set value(val) {
this.setAttribute('value', val);
}
将 value
属性设置为
<vi-textfield value="[val]">
不是
上的value
属性
<input id="vi-input" type="text" value="${this.getAttribute("value")}"/>
这是您的元素 shadowDOM 中的另一个 元素
value="${this.getAttribute("value")}"
运行 一次,因为 connectedCallback()
运行 一次
如果你想同时设置,你可以这样做:
set value(val) {
this.setAttribute('value', val);
this.shadowRoot.getElementById("vi-input").setAttribute("value", val);
}
如果你想让它们同步,你还需要 setAttribute 代码用于 value
输入变化时。
PS.
set readonly(val) {
if (val) {
this.setAttribute("readonly", '');
} else {
this.removeAttribute("readonly");
}
}
可以写成:
set readonly(val) {
this.toggleAttribute("readonly", val);
}