webcomponent 入门篇之伪类/伪元素的使用

前言

上一篇webcomponent 入门篇之实现一个简单组件webcomponent 进行了简单的介绍,并且利用 webcomponent 实现了一个简单的按钮组件。本篇文章将接着上一篇的内容,重点介绍一下 webcomponent 中特殊的伪类/伪元素的使用。

webcomponent 中的伪类/伪元素会有一些特殊处理,主要有以下五个伪类/伪元素会有一些巧妙的作用。

:defined

这个伪类用于选中任何已定义的元素。

与已定义的元素相对,在自定义元素中,如果出现一些语法错误,或者在不同的浏览器中因为兼容性不同会产生一些错误以及其他任何错误,将会被浏览器识别为未定义元素。在这个时候自定义元素的展示将会遇到问题。

如下代码所示,我们就可以灵活利用:defined,设置未定义元素不展示。需要注意的是,这个伪类 css 不要写在template中,需要写在全局,不然样式可能会出现问题。

提示:以下代码写了一个简单的组件,接下来的代码展示将都会在这个组件上面展开。

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
</head>
<style>
  custom-div:defined {
    display: block;
	}
  custom-div:not(:defined) {
    display: none;
  }
</style>
<body>
<custom-div></custom-div>
<template id="customDivTemplate">
  <style>
   .container {
     color: #333;
   }
  </style>
  <div class="container"> custom-div </div>
</template>

</body>
</html>
class CustomDiv extends HTMLElement {
  constructor() {
    super();
    var templateElem = document.getElementById('customDivTemplate');
    var content = templateElem.content.cloneNode(true);
    this.attachShadow( { mode: 'closed' } ).appendChild(content);
  }
}
window.customElements.define('custom-div', CustomDiv);

:host/:host()

此伪类用于选中 shadow DOM 的宿主,而 :host:host()的区别是后者能够指定需要生效的元素。

比如,通过 :host:host(),我们可以单独维护自定义元素中的css变量。

举个例子,我们通过:hostcustom-div 的背景色变量设置为orange,通过 :host()来分别选中类名为 a 的组件以及含有 pink 属性设置的组件,修改它们的背景色变量。

<custom-div class="a"></custom-div>
<custom-div></custom-div>
<custom-div pink></custom-div>
<template id="customDivTemplate">
  <style>
   :host {
     --background-color: orange;
   }
   :host(.a) {
     --background-color: yellow;
   }
   :host([pink]) {
     --background-color: pink;
   }
   .container {
     background-color: var(--background-color);
     padding: 16px;
     border-radius: 10px;
     color: #333;
     text-align: center;
   }
  </style>
  <div class="container"> custom-div </div>
</template>

效果如图所示:

webcomponent 入门篇之伪类/伪元素的使用

:host-context()

这个伪类也是用于选中 shadow DOM 的,区别是它是用来指定父元素的。

举个例子,下面有个 custom-div 的父元素是类名为 big,我们可以通过 :host-context() 来指定只有类名为 big 的子元素的宽度与背景色。

<custom-div pink></custom-div>
<div class="big">
  <custom-div pink></custom-div>
</div>
<template id="customDivTemplate">
  <style>
   :host {
     --background-color: orange;
     --width: 300px;
   }
   :host([pink]) {
     --background-color: pink;
   }
   :host-context(.big) {
     --width: 500px;
     --background-color: yellow;
   }
   .container {
     background-color: var(--background-color);
     padding: 16px;
     width: var(--width);
     border-radius: 10px;
     color: #333;
     text-align: center;
   }
  </style>
  <div class="container"> custom-div </div>
</template>
</body>
</html>

webcomponent 入门篇之伪类/伪元素的使用

::slotted()

此伪元素可以用来设置通过 slot 插槽 插入到 shadow DOM 的元素样式。

如下示例,组件中添加了一个命名为 prefix 的插槽,使用组件时通过插槽插入了一个属性为 purplespan 。通过 ::slotted()可以设置指定类名、属性或者全部元素的样式,比如下面这个我们就是设置了还有 purple属性的 slot的字重和字色。

<custom-div class="a"></custom-div>
<custom-div><span slot="prefix" purple>在前面</span></custom-div>

<template id="customDivTemplate">
  <style>
    :host {
      --background-color: orange;
      --width: 300px;
    }
    :host(.a) {
      --background-color: yellow;
    }
    ::slotted([purple]) {
      font-weight:bolder;
      color: purple;
    }
    .container {
      background-color: var(--background-color);
      padding: 16px;
      width: var(--width);
      border-radius: 10px;
      color: #333;
      text-align: center;
    }
  </style>
  <div class="container">
    <slot name="prefix"></slot>
    custom-div
  </div>
</template>

webcomponent 入门篇之伪类/伪元素的使用

总结

伪类/伪元素 作用
:defined 用于选中任何已定义的元素,包括任何浏览器内置的标准元素以及已成功定义的自定义元素。
:host 用于选中 shadow DOM 的宿主。
:host() 选中 shadow DOM 的宿主并指定带有特定选择器的 shadow DOM 宿主
:host-context() 用于选中作为特定选择器后代的 shadow DOM 宿主,注意它和 :host 伪类的区别,:host 伪类选中的是自身带有特定选择器的宿主。
::slotted() 用于选中通过 插入到 shadow DOM 中的元素。

参考代码

后记

本篇文章是关于 webcomponent 伪类/伪元素的使用,通过这些伪类/伪元素,增强了 webcomponent 的玩法,提供了一些便利,有兴趣的同学赶紧尝试起来吧。

参考文章

  1. developer.mozilla.org/zh-CN/docs/…
  2. www.qingcong.tech/technology/…

原文链接:https://juejin.cn/post/7314093226956308490 作者:阿李贝斯

(0)
上一篇 2023年12月19日 下午4:10
下一篇 2023年12月19日 下午4:21

相关推荐

发表回复

登录后才能评论