javascript七基础学习系列一千四百八十九:反射自定义元素属性

自定义元素既是DOM 实体又是JavaScript 对象,因此两者之间应该同步变化。换句话说,对DOM
的修改应该反映到JavaScript 对象,反之亦然。要从JavaScript 对象反射到DOM,常见的方式是使用获
取函数和设置函数。下面的例子演示了在JavaScript 对象和DOM 之间反射bar 属性的过程:
document.body.innerHTML = <x-foo></x-foo>;
class FooElement extends HTMLElement {
constructor() {
super();
this.bar = true;
}
get bar() {
return this.getAttribute(‘bar’);
}
set bar(value) {
this.setAttribute(‘bar’, value)
}
}
customElements.define(‘x-foo’, FooElement);
console.log(document.body.innerHTML);
//
另一个方向的反射(从DOM 到JavaScript 对象)需要给相应的属性添加监听器。为此,可以使用
observedAttributes()获取函数让自定义元素的属性值每次改变时都调用attributeChanged-
Callback():
class FooElement extends HTMLElement {
static get observedAttributes() {
// 返回应该触发attributeChangedCallback()执行的属性
return [‘bar’];
}
get bar() {
return this.getAttribute(‘bar’);
}
set bar(value) {
this.setAttribute(‘bar’, value)
}
attributeChangedCallback(name, oldValue, newValue) {
if (oldValue !== newValue) {
console.log(${oldValue} -> ${newValue});
this[name] = newValue;
}
}
}
customElements.define(‘x-foo’, FooElement);
document.body.innerHTML = <x-foo bar="false"></x-foo>;
// null -> false
document.querySelector(‘x-foo’).setAttribute(‘bar’, true);
// false -> true
升级自定义元素
并非始终可以先定义自定义元素,然后再在DOM 中使用相应的元素标签。为解决这个先后次序问
题,Web 组件在CustomElementRegistry 上额外暴露了一些方法。这些方法可以用来检测自定义元
素是否定义完成,然后可以用它来升级已有元素。
如果自定义元素已经有定义,那么CustomElementRegistry.get()方法会返回相应自定义元素
的类。类似地,CustomElementRegistry.whenDefined()方法会返回一个期约,当相应自定义元素
有定义之后解决:
customElements.whenDefined(‘x-foo’).then(() => console.log(‘defined!’));
console.log(customElements.get(‘x-foo’));
// undefined
customElements.define(‘x-foo’, class {});
// defined!
console.log(customElements.get(‘x-foo’));
// class FooElement {}
连接到DOM的元素在自定义元素有定义时会自动升级。如果想在元素连接到DOM 之前强制升级,
可以使用CustomElementRegistry.upgrade()方法:
// 在自定义元素有定义之前会创建HTMLUnknownElement 对象
const fooElement = document.createElement(‘x-foo’);
// 创建自定义元素
class FooElement extends HTMLElement {}
customElements.define(‘x-foo’, FooElement);
console.log(fooElement instanceof FooElement); // false
// 强制升级
customElements.upgrade(fooElement);
console.log(fooElement instanceof FooElement); // true

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值