Custom Elements其他概念

281 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第4天,点击查看活动详情

渲染时机

  • 一般来说对于Custom Elements的类,我们一般将结构的定义放在constructor,将内容的渲染放在connectedCallback中

    • 因为对于内容的渲染,往往会用到Custom Elements 的Attribute,而在constructor调用时,虽然元素已经被创建,但此时还未被插入页面,因此在此时浏览器还无法处理该元素的属性,调用getAttribute的话就会返回null,而在connectedCallback被调用时,该元素已经成为文档的一部分.
    • 因此我们可以构建分离的DOM,为之后的使用提前创建好元素,然后在插入文档时进行渲染。

渲染顺序

  • 当多个Custom Elements嵌套使用时,与HTML的嵌套渲染类似,HTML会先创建外层的元素并加入DOM,然后才会将内层的元素创建并加入DOM,Custom Elements外层元素的渲染也不会等待内层元素的渲染。
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<script>
    customElements.define('custom-test', class extends HTMLElement {
      connectedCallback() {
        console.log(this.innerHTML)
        console.log(this.content)
      }
    });
 </script>
<body>
    <custom-test content=“test content”>
        Test content
     </custom-test>
</body>
</html>

以上代码的输出值为空白,这是因为在该元素创建时,内层元素还未创建,于是此时获取内层元素的值时便会得到空值,所有我们需要给Custom Elements传入信息时,我们可以使用Attribute,这个是可以即时生效的,或者使用SetTimeout在稍后对子元素进行访问。

CustomElementRegistry接口

  • customElements.get(name)

    • name: 希望返回引用的自定义元素的名字
    • return: 返回指定名字自定义元素的构造函数,如果没有则返回undefined
  • customElements.whenDefined(name):

    • name: 希望返回引用的自定义元素的名字
    • return: 返回一个 promise,将会在这个具有给定 name 的 custom element 变为已定义状态的时候 resolve(不带值),如果元素已被定义,则resolve立即执行
  • CustomElementRegistry.upgrade(root): 更新节点子树中所有包含阴影的自定义元素,甚至在它们连接到主文档之前也是如此。

    • root: 待升级的包含阴影的派生元素节点 。如果没有可升级的派生实例,则不会抛出异常。

Custom elements升级,在未执行customElements.defined()方法之前,文档中已经存在的自定义元素,并不会使得浏览器报错,而是会被当成一个非标准的标签,当customElements.defined(),此时Custom Elements元素为每个标签都创建了。

代码来自HTML规范

const el = document.createElement("spider-man");
​
class SpiderMan extends HTMLElement {}
customElements.define("spider-man", SpiderMan);
​
console.assert(!(el instanceof SpiderMan)); // not yet upgraded
​
customElements.upgrade(el);
console.assert(el instanceof SpiderMan);    // upgraded!

CSS伪类

  • :defined: 表示任何已定义的元素。这包括任何浏览器内置的标准元素以及已成功定义的自定义元素

    • 在customElement.define被调用之前,:defined选择器并不能选择该元素,只有customElement.define调用之后,并且connectCallback被调用之后,该标签才会被:defiend选中。
  • :not():用来匹配不符合一组选择器的元素。由于它的作用是防止特定的元素被选中,它也被称为反选伪类

    • 我们可以用:not(:defined)来对未定义的Custom Elements元素进行选中,并设置他们的样式