惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

雷峰网
雷峰网
N
Netflix TechBlog - Medium
博客园_首页
J
Java Code Geeks
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Y
Y Combinator Blog
腾讯CDC
V
V2EX
Microsoft Security Blog
Microsoft Security Blog
大猫的无限游戏
大猫的无限游戏
Cyberwarzone
Cyberwarzone
N
News and Events Feed by Topic
L
LINUX DO - 最新话题
Schneier on Security
Schneier on Security
Microsoft Azure Blog
Microsoft Azure Blog
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Hacker News: Ask HN
Hacker News: Ask HN
Martin Fowler
Martin Fowler
Google DeepMind News
Google DeepMind News
G
Google Developers Blog
U
Unit 42
WordPress大学
WordPress大学
N
News and Events Feed by Topic
S
Schneier on Security
T
The Blog of Author Tim Ferriss
B
Blog
博客园 - 叶小钗
Forbes - Security
Forbes - Security
F
Fortinet All Blogs
Project Zero
Project Zero
K
Kaspersky official blog
Apple Machine Learning Research
Apple Machine Learning Research
L
LINUX DO - 热门话题
The GitHub Blog
The GitHub Blog
H
Hacker News: Front Page
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
PCI Perspectives
PCI Perspectives
The Register - Security
The Register - Security
www.infosecurity-magazine.com
www.infosecurity-magazine.com
W
WeLiveSecurity
C
Cyber Attacks, Cyber Crime and Cyber Security
罗磊的独立博客
S
Security @ Cisco Blogs
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
T
Tailwind CSS Blog
P
Proofpoint News Feed
S
SegmentFault 最新的问题
D
Docker
量子位
M
MIT News - Artificial intelligence

博客园 - 饭特稠

浪浪山老前端的2025 useAttrs 是响应式的吗(by 豆包) 实时互动教育版的自定义 UI 如何开发 2024,在路上 当蓝牙键盘连不上电脑:一次意外的debug之旅 前端技术选型时有用的网站 好用的zsh插件,打造好用的命令行 2023年终总结:怀孕,装修,还贷和其他 分享一个URL正则 使用 scriptable 实现每日诗词小组件 如何使webpack编译 node_modules 中的 npm 包 小程序中实现图片旋转后保存 CSS 原生嵌套来了 聊聊CSS 缓动函数的新成员linear() chatgpt: 在ts中如何声明一个全局类型 Workbox -- 为serviceWorker量身定做的工具 cache API简介 重新学车 魔幻2022
Custom Elements 和 Shadow DOM了解一下?
饭特稠 · 2023-07-31 · via 博客园 - 饭特稠

Why

在最近参与的一个项目中,有使用 Vue 创建 Custom Elements的代码,与传统的单 Vue 实例 render 到 DOM 节点有很大不同。所以有了本文。

Custom Elements

首先我们来看看怎么创建一个自定义元素,假如我们要实现一个抽屉元素:

class AppDrawerElement extends HTMLElement {...}
window.customElements.define('app-drawer', AppDrawerElement);

这里我们定义了一个AppDrawerElement类,将它实例化就可以得到一个抽屉元素,正如我们创建一个 button 时,其实是一个HTMLButtonElement的实例一样,在第二行代码中,我们将抽屉元素对应的HTML标签命名为'app-drawer';接下来我们就可以创建一个抽屉元素,并插入到 Body 中了

const drawer = document.createElement('drawer');
document.body.appendChild(drawer);

但是这样的 element 毫无用处,也不能显示隐藏, 我们希望它能显示隐藏,那么需要完善AppDrawerElement的实现,主要包含constructor connectedCallback , disconnectedCallback ,attributeChangedCallback等方法,他们的职责分别是:

实现上述方法后代码如下:

class AppDrawer extends HTMLElement {
  constructor() {
    super(); // always call super() first in the constructor.
  }
  static get observedAttributes() { // 哪些属性的变化可以触发 attributeChangedCallback
    return ['open'];
  }
   get open() {
    return this.hasAttribute('open');
  }

  set open(val) {
    if (val) {
      this.setAttribute('open', '');
    } else {
      this.removeAttribute('open');
    }
    this.toggleDrawer();
  }
  toggleDrawer() {
    console.log(this.open);
      if (this.open) {
        this.children[0].style.cssText="display: block;"
      } else {
        this.children[0].style.cssText = 'display: none';
      }
  }

  connectedCallback() {
    // ...
    this.innerHTML = '<div style="display:none">drawer</div>';
  }

  disconnectedCallback() {
    // ...
  }

  attributeChangedCallback(attrName, oldVal, newVal) {
    console.log(attrName, oldVal, newVal);
    if (attrName === 'open') {
        this.toggleDrawer();
     }
    // ...
  }
}

这里要注意下observedAttributes这个静态属性,在这个属性中的 attribute 名才会触发 attributeChangedCallback,除此之外如 class,style 的变化不会触发回调函数。

虽然现在可以显示隐藏了,但是如何在元素中自定义 css 并且不影响全局呢,此外像 Vue 中的 slot 又改如何实现,这里就要用到 Shadow DOM了

Shadow DOM

Shadow DOM最重要的功能之一是实现了样式隔离,当我们在开发一个大型前端项目时,随着 CSS 样式越来越多,很可能会遇到样式冲突的问题,为了解决这个问题,社区给出了 CSS-modules,scoped css等方案,而 Shadow DOM Web 标准给出的方案。

在 Shadow DOM 中的元素不会受到外部样式的影响,而 Shadow DOM 中的样式也不会影响到外部元素。

参考文档