热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

JavaScript是怎样事情:ShadowDOM的内部结构+怎样编写自力的组件!

这是特地探究JavaScript及其所构建的组件的系列文章的第17篇。想浏览更多优良文章请猛戳GitHub博客,一年百来篇优良文章等着你!假如你错过了前面的章节,能够在这里找到它们

这是特地探究 Javascript 及其所构建的组件的系列文章的第 17 篇。

想浏览更多优良文章请猛戳GitHub博客,一年百来篇优良文章等着你!

假如你错过了前面的章节,能够在这里找到它们:

  1. Javascript 是怎样事情的:引擎,运行时和挪用客栈的概述!
  2. Javascript 是怎样事情的:深切V8引擎&编写优化代码的5个技能!
  3. Javascript 是怎样事情的:内存治理+怎样处置惩罚4个罕见的内存走漏!
  4. Javascript 是怎样事情的:事宜轮回和异步编程的兴起+ 5种运用 async/await 更好地编码体式格局!
  5. Javascript 是怎样事情的:深切探究 websocket 和HTTP/2与SSE +怎样挑选准确的途径!
  6. Javascript 是怎样事情的:与 WebAssembly比较 及其运用处景!
  7. Javascript 是怎样事情的:Web Workers的构建块+ 5个运用他们的场景!
  8. Javascript 是怎样事情的:Service Worker 的生命周期及运用处景!
  9. Javascript 是怎样事情的:Web 推送关照的机制!
  10. Javascript是怎样事情的:运用 MutationObserver 跟踪 DOM 的变化!
  11. Javascript是怎样事情的:衬着引擎和优化其机能的技能!
  12. Javascript是怎样事情的:深切收集层 + 怎样优化机能和平安!
  13. Javascript是怎样事情的:CSS 和 JS 动画底层道理及怎样优化它们的机能!
  14. Javascript的怎样事情的:剖析、笼统语法树(AST)+ 提拔编译速率5个技能!
  15. Javascript是怎样事情的:深切类和继续内部道理+Babel和 TypeScript 之间转换!
  16. Javascript是怎样事情的:存储引擎+怎样挑选适宜的存储API!

《Javascript 是怎样事情: Shadow DOM 的内部结构+怎样编写自力的组件!》

概述

Web Components 是一套差别的手艺,许可你建立可重用的定制元素,它们的功用封装在你的代码以外,你能够在 Web 运用中运用它们。

Web组件由四部份构成:

  • Shadow DOM(影子DOM)
  • HTML templates(HTML模板)
  • Custom elements(自定义元素)
  • HTML Imports(HTML导入)

在本文中重要解说 Shadow DOM(影子DOM)

Shadow DOM 这款东西旨在构建基于组件的运用。因而,可为收集开辟中的罕见问题供应处理方案:

  • 断绝 DOM:组件的 DOM 是自力的(比方,document.querySelector() 不会返回组件 shadow DOM 中的节点)。
  • 作用域 CSS:shadow DOM 内部定义的 CSS 在其作用域内。款式划定规矩不会走漏,页面款式也不会渗透。
  • 组合:为组件设想一个声明性、基于标记的 API。
  • 简化 CSS – 作用域 DOM 意味着您能够运用简朴的 CSS 挑选器,更通用的 id/类称号,而无需忧郁定名争执。

Shadow DOM

本文假定你已熟习 DOM 及别的的 Api 的观点。假如不熟习,能够在这里浏览关于它的细致文章—— https://developer.mozilla.org…。

暗影 DOM 只是一个平常的 DOM,除了两个区分:

  • 建立/运用的体式格局
  • 与页面其他部份有关的行动体式格局

    平常,你建立 DOM 节点并将其附加至其他元素作为子项。 借助于 shadow DOM,您能够建立作用域 DOM 树,该 DOM 树附加至该元素上,但与其自身真正的子项星散开来。这一作用域子树称为影子树。被附着的元素称为影子宿主。 您在影子中增加的任何项均将成为宿主元素的当地项,包括





    Launch



    模板 (Templates)

    假如须要 Web 页面上反复运用雷同的标签组织时,最好运用某种范例的模板,而不是一遍又一各处反复雷同的组织。这在之前也是能够完成,然则 HTML

    如今自定义组件能够如许运用:


    元素

    模板有一些瑕玷,重如果静态内容,它不许可我们衬着变量/数据,好能够让我们根据平常运用的规范 HTML 模板的习气来编写代码。Slot 是组件内部的占位符,用户能够运用自身的标记来添补。让我们看看上面的模板怎样运用 slot


    假如在标记中包括元素时没有定义插槽的内容,或许浏览器不支撑插槽, 就只展现文本 “Default text”

    为了定义插槽的内容,应该在 元素中包括一个 HTML 组织,个中的 slot 属性的值为我们定义插槽的称号:


    Let's have some different text!

    能够插进去插槽的元素称为 Slotable; 当一个元素插进去一个插槽时,它被称为开槽 (slotted)。

    注重,在上面的例子中,插进去了一个 元素,它是一个开槽元素,它有一个属性 slot,它即是 my-text,与模板中的 slot 定义中的 name 属性的值雷同。

    在浏览器中衬着后,上面的代码将构建以下扁平 DOM 树:


    #shadow-root



    Let's have some different text!



    设定款式

    运用 shadow DOM 的组件可经由过程主页来设定款式,定义其自身的款式或供应钩子(以 CSS 自定义属性的情势)让用户替代默许值。

    组件定义的款式

    作用域 CSS 是 Shadow DOM 最大的特征之一:

    • 外部页面的 CSS 挑选器不运用于组件内部
    • 组件内定义的款式不会影响页面的其他元素,它们的作用域是宿主元素

    shadow DOM 内部运用的 CSS 挑选器在当地运用于组件现实上,这意味着我们能够再次运用大众vid/类名,而不必忧郁页面上其他地方的争执,最好做法是在 Shadow DOM 内运用更简朴的 CSS 挑选器,它们在机能上也不错。

    看看在 #shadow-root 定义了一些款式的:

    #shadow-root



    上面例子中的一切款式都是#shadow-root的当地款式。运用元素在#shadow-root中引入款式表,这些款式表也都属于当地的。

    :host 伪类挑选器

    运用 :host 伪类挑选器,用来挑选组件宿主元素中的元素 (相关于组件模板内部的元素)。


    当涉及到 :host 挑选器时,应该警惕一件事:父页面中的划定规矩具有比元素中定义的 :host 划定规矩具有更高的优先级,这许可用户从外部掩盖顶级款式。而且 :host 只在影子根目录下事情,所以你不能在Shadow DOM 以外运用它。

    假如 :host() 的函数情势与 婚配,你能够指定宿主,关于你的组件而言,这是一个很好的要领,它可以让你基于宿主将对用户互动或状况的回响反映行动举行封装,或对内部节点举行款式设定:


    :host-context()

    :host-context() 或其恣意父级与 婚配,它将与组件婚配。 比方,在文档的元素上能够有一个用于示意款式主题 (theme) 的 CSS 类,而我们应该基于它来决议组件的款式。
    比方,很多人都经由过程将类运用到 或 举行主题化:






    鄙人面的例子中,只有当某个先人元素有 CSS 类theme-light时,我们才会把background-color款式运用到组件内部的一切元素中:

    :host-context(.theme-light) h2 {
    background-color: #eef;
    }

    /deep/

    组件款式平常只会作用于组件自身的 HTML 上,我们能够运用 /deep/ 挑选器,来强迫一个款式对各级子组件的视图也见效,它不只作用于组件的子视图,也会作用于组件的内容。

    鄙人面例子中,我们以一切的元素为目的,从宿主元素到当前元素再到 DOM 中的一切子元素:

    :host /deep/ h3 {
    font-style: italic;
    }

    /deep/ 挑选器另有一个别号 >>>,能够恣意交替运用它们。

    /deep/
    >>> 挑选器只能被用在
    仿真 (emulated)形式下。 这类体式格局是默许值,也是用得最多的体式格局。

    从外部为组件设定款式

    有几种要领可从外部为组件设定款式:最简朴的要领是运用标记称号作为挑选器,以下

    custom-container {
    color: red;
    }

    外部款式比在 Shadow DOM 中定义的款式具有更高的优先级。

    比方,假如用户编写挑选器:

    custom-container {
    width: 500px;
    }

    它将掩盖组件的款式:

    :host {
    width: 300px;
    }

    对组件自身举行款式化只能到此为止。然则假如人想要对组件的内部举行款式化,会发作什么情况呢?为此,我们须要 CSS 自定义属性。

    运用 CSS 自定义属性建立款式钩子

    假如组件的开辟者经由过程 CSS 自定义属性供应款式钩子,则用户可调解内部款式。其头脑相似于,但适用于款式。

    看看下面的例子:




    在其 shadow DOM 内部:

    :host([background]) {
    background: var( - custom-container-bg, #CECECE);
    border-radius: 10px;
    padding: 10px;
    }

    在本例中,该组件将运用 black 作为背景值,由于用户指定了该值,不然,背景色彩将采纳默许值 #CECECE

    作为组件的作者,是有义务让开辟人员相识他们能够运用的 CSS 定制属性,将其视为组件的大众接口的一部份。

    在 JS 中运用 slot

    Shadow DOM API 供应了运用 slot 和散布式节点的实用程序,这些实用程序在编写自定义元素时早晚派得上用处。

    slotchange 事宜

    slot 的散布式节点发作变化时,slotchange 事宜将触发。比方,假如用户从 light DOM 中增加/删除子元素。

    var slot = this.shadowRoot.querySelector('#some_slot');
    slot.addEventListener('slotchange', function(e) {
    console.log('Light DOM change');
    });

    要看管对 light DOM 的其他范例的变动,能够在元素的组织函数中运用 MutationObserver。之前讨论过 MutationObserver 的内部组织以及怎样运用它。

    assignedNodes() 要领

    有时候,相识哪些元素与 slot 相关联异常有效。挪用 slot.assignedNodes() 可检察 slot 正在衬着哪些元素。 {flatten: true} 选项将返回 slot 的备用内容(条件是没有散布任何节点)。

    让我们看看下面的例子:

    Default content


    假定这是在一个名为 的组件中。

    看看这个组件的差别用法,以及挪用 assignedNodes() 的效果是什么:

    在第一种情况下,我们将向 slot 中增加我们自身的内容:


    container text

    挪用 assignedNodes() 会取得 [ container text ],注重,效果是一个节点数组。

    在第二种情况下,将内容置空:


    挪用 assignedNodes() 的效果将返回一个空数组 []

    在第三种情况下,挪用 slot.assignedNodes({flatten: true}),取得效果是: [

    默许内容

    ]

    另外,要接见 slot 中的元素,能够挪用 assignedNodes() 来检察元素分配给哪一个组件 slot

    事宜模子

    值得注重的是,当发作在 Shadow DOM 中的事宜冒泡时,会发作什么。

    当事宜从 Shadow DOM 中触发时,其目的将会调解为保持 Shadow DOM 供应的封装。也就是说,事宜的目的从新举行了设定,因而这些事宜看起来像是来自组件,而不是来自 Shadow DOM 中的内部元素。

    下面是从 Shadow DOM 流传出去的事宜列表(有些没有):

    • 聚焦事宜:blur、focus、focusin、focusout
    • 鼠标事宜:click、dblclick、mousedown、mouseenter、mousemove,等等
    • 滚轮事宜:wheel
    • 输入事宜:beforeinput、input
    • 键盘事宜:keydown、keyup
    • 组合事宜:compositionstart、compositionupdate、compositionend
    • 拖放事宜:dragstart、drag、dragend、drop,等等

    自定义事宜

    默许情况下,自定义事宜不会流传到 Shadow DOM 以外。假如愿望分配自定义事宜并使其流传,则须要增加 bubbles: truecomposed: true 选项。

    让我们看看派发如许的事宜是什么样的:

    var cOntainer= this.shadowRoot.querySelector('#container');
    container.dispatchEvent(new Event('containerchanged', {bubbles: true, composed: true}));

    浏览器支撑

    如愿望取得 shadow DOM 检测功用,请检察是不是存在 attachShadow:

    const supportsShadowDOMV1 = !!HTMLElement.prototype.attachShadow;

    《Javascript 是怎样事情: Shadow DOM 的内部结构+怎样编写自力的组件!》

    有史以来第一次,我们具有了实行恰当 CSS 作用域、DOM 作用域的 API 原语,而且有真正意义上的组合。 与自定义元素等其他收集组件 API 组合后,shadow DOM 供应了一种编写真正封装组件的要领,无需花多大的工夫或运用如 等陈腐的东西。

    代码布置后能够存在的BUG没法及时晓得,预先为相识决这些BUG,花了大批的时候举行log 调试,这边顺便给人人引荐一个好用的BUG监控东西 Fundebug。

    你的点赞是我延续分享好东西的动力,迎接点赞!

    迎接到场前端人人庭,内里会常常分享一些手艺资本。

    《Javascript 是怎样事情: Shadow DOM 的内部结构+怎样编写自力的组件!》


推荐阅读
  • 本文介绍了前端人员必须知道的三个问题,即前端都做哪些事、前端都需要哪些技术,以及前端的发展阶段。初级阶段包括HTML、CSS、JavaScript和jQuery的基础知识。进阶阶段涵盖了面向对象编程、响应式设计、Ajax、HTML5等新兴技术。高级阶段包括架构基础、模块化开发、预编译和前沿规范等内容。此外,还介绍了一些后端服务,如Node.js。 ... [详细]
  • Android实战——jsoup实现网络爬虫,糗事百科项目的起步
    本文介绍了Android实战中使用jsoup实现网络爬虫的方法,以糗事百科项目为例。对于初学者来说,数据源的缺乏是做项目的最大烦恼之一。本文讲述了如何使用网络爬虫获取数据,并以糗事百科作为练手项目。同时,提到了使用jsoup需要结合前端基础知识,以及如果学过JS的话可以更轻松地使用该框架。 ... [详细]
  • 本文介绍了2015年九月八日的js学习总结及相关知识点,包括参考书《javaScript Dom编程的艺术》、js简史、Dom、DHTML、解释型程序设计和编译型程序设计等内容。同时还提到了最佳实践是将标签放到HTML文档的最后,并且对语句和注释的使用进行了说明。 ... [详细]
  • 本文介绍了C#中生成随机数的三种方法,并分析了其中存在的问题。首先介绍了使用Random类生成随机数的默认方法,但在高并发情况下可能会出现重复的情况。接着通过循环生成了一系列随机数,进一步突显了这个问题。文章指出,随机数生成在任何编程语言中都是必备的功能,但Random类生成的随机数并不可靠。最后,提出了需要寻找其他可靠的随机数生成方法的建议。 ... [详细]
  • 使用在线工具jsonschema2pojo根据json生成java对象
    本文介绍了使用在线工具jsonschema2pojo根据json生成java对象的方法。通过该工具,用户只需将json字符串复制到输入框中,即可自动将其转换成java对象。该工具还能解析列表式的json数据,并将嵌套在内层的对象也解析出来。本文以请求github的api为例,展示了使用该工具的步骤和效果。 ... [详细]
  • Voicewo在线语音识别转换jQuery插件的特点和示例
    本文介绍了一款名为Voicewo的在线语音识别转换jQuery插件,该插件具有快速、架构、风格、扩展和兼容等特点,适合在互联网应用中使用。同时还提供了一个快速示例供开发人员参考。 ... [详细]
  • 解决Cydia数据库错误:could not open file /var/lib/dpkg/status 的方法
    本文介绍了解决iOS系统中Cydia数据库错误的方法。通过使用苹果电脑上的Impactor工具和NewTerm软件,以及ifunbox工具和终端命令,可以解决该问题。具体步骤包括下载所需工具、连接手机到电脑、安装NewTerm、下载ifunbox并注册Dropbox账号、下载并解压lib.zip文件、将lib文件夹拖入Books文件夹中,并将lib文件夹拷贝到/var/目录下。以上方法适用于已经越狱且出现Cydia数据库错误的iPhone手机。 ... [详细]
  • 计算机存储系统的层次结构及其优势
    本文介绍了计算机存储系统的层次结构,包括高速缓存、主存储器和辅助存储器三个层次。通过分层存储数据可以提高程序的执行效率。计算机存储系统的层次结构将各种不同存储容量、存取速度和价格的存储器有机组合成整体,形成可寻址存储空间比主存储器空间大得多的存储整体。由于辅助存储器容量大、价格低,使得整体存储系统的平均价格降低。同时,高速缓存的存取速度可以和CPU的工作速度相匹配,进一步提高程序执行效率。 ... [详细]
  • 本文介绍了绕过WAF的XSS检测机制的方法,包括确定payload结构、测试和混淆。同时提出了一种构建XSS payload的方法,该payload与安全机制使用的正则表达式不匹配。通过清理用户输入、转义输出、使用文档对象模型(DOM)接收器和源、实施适当的跨域资源共享(CORS)策略和其他安全策略,可以有效阻止XSS漏洞。但是,WAF或自定义过滤器仍然被广泛使用来增加安全性。本文的方法可以绕过这种安全机制,构建与正则表达式不匹配的XSS payload。 ... [详细]
  • JavaScript和HTML之间的交互是经由过程事宜完成的。事宜:文档或浏览器窗口中发作的一些特定的交互霎时。能够运用侦听器(或处置惩罚递次来预订事宜),以便事宜发作时实行相应的 ... [详细]
  • 本文总结了在编写JS代码时,不同浏览器间的兼容性差异,并提供了相应的解决方法。其中包括阻止默认事件的代码示例和猎取兄弟节点的函数。这些方法可以帮助开发者在不同浏览器上实现一致的功能。 ... [详细]
  • 《从零构建前后星散的web项目》:前端相识过关了吗?
    #前端基本架构和硬核引见手艺栈的挑选起首我们构建前端架构须要对前端生态圈有统统相识,而且最好带有肯定的手艺前瞻性,好的手艺架构能够日后会轻易的扩大,削减重构的次数,纵然重构也不须要 ... [详细]
  • [译]技术公司十年经验的职场生涯回顾
    本文是一位在技术公司工作十年的职场人士对自己职业生涯的总结回顾。她的职业规划与众不同,令人深思又有趣。其中涉及到的内容有机器学习、创新创业以及引用了女性主义者在TED演讲中的部分讲义。文章表达了对职业生涯的愿望和希望,认为人类有能力不断改善自己。 ... [详细]
  • Go Cobra命令行工具入门教程
    本文介绍了Go语言实现的命令行工具Cobra的基本概念、安装方法和入门实践。Cobra被广泛应用于各种项目中,如Kubernetes、Hugo和Github CLI等。通过使用Cobra,我们可以快速创建命令行工具,适用于写测试脚本和各种服务的Admin CLI。文章还通过一个简单的demo演示了Cobra的使用方法。 ... [详细]
  • WebSocket与Socket.io的理解
    WebSocketprotocol是HTML5一种新的协议。它的最大特点就是,服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息,是真正的双向平等对话,属于服务器推送 ... [详细]
author-avatar
虚伪小仔
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有