Web组件

 开发者使用Vue、React等框架来使用及创建定制的组件,Web组件是浏览器原生支持的替代这些框架的特性,主要涉及相对比较新的三个Web标准。这些Web标准允许JS使用新标签扩展HTML,扩展后的标签就是自成一体的、可重用的UI组件。

 1 HTML模版

DocumentFragment是一种Node类型,可以临时充当一组同辈节点的父节点,方便将这些同辈节点作为一个单元来使用。可以使用document.createDocumentFragment()来创建DocumentFragment节点。创建DocumentFragment节点后,可以像使用Element一样。

DocumentFragment与Element的区别是在于它没有父节点,当向文档中插入DocumentFragment节点时,DocumentFragment本身并不会被插入,实际上插入的是它的子节点。

1.1 <template>标签

<template>标签及其子元素永远不会被浏览器渲染,其对应的是一个HTMLTemplateElement对象,这个对象只定义了一个content属性,该属性值是包含<template>所以子节点的DocumentFragment。

可以深度克隆这个DocumentFragment,然后把克隆的副本插入文档中需要的地方。

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<template id="tep"><div class="grid"></div>
</template>
<div class="block"><span>hello block</span>
</div>
</body>
<script>let tep = document.querySelector("#tep");let block = document.querySelector(".block");block.append(tep.content.cloneNode(true));//深度克隆block.append(tep.content.cloneNode(true));
</script>
</html>
<style>.grid{width: 50px;height: 50px;background: blue;margin: 10px;}
</style>

2 自定义元素

customElement.define()方法用来自定义元素。第一个参数是标签名(必须包含一个连字符),第二个参数是HTMLElement的子类。

浏览器会自动调用自定义元素类的特定“生命期方法”,当自定义元素被插入文档时,会调用connectedCallback()方法;当自定义元素从文档中被移除时会调用disconnectedCallback()方法。

如果自定义元素定义了静态的observedAttributes属性,其值为一个属性名的数组,且如果任何这些命名属性在这个自定义元素的一个实例上被设置(或修改),浏览器会调用attributeChangeCallback()方法。这个回调可以根据属性值的变化采取必要的步骤以更新组件。

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<button onclick="createCus()">添加元素</button>
<button onclick="removeCus()">移除元素</button>
<button onclick="addSize()">增加尺寸</button>
<button onclick="changeColor()">修改颜色属性</button>
<div id="block"></div>
</body>
</html><script>class CustomCircle extends HTMLElement {connectedCallback() {this.style.borderRadius = "50%";this.style.border = "solid black 1px"this.style.display = "block"this.style.width = "50px";this.style.height = "50px";this.classList.add("custom")this.customSize = 50;console.log("元素被添加到文档");}disconnectedCallback() {console.log("元素被移除");}static get observedAttributes() {return ["cus"];}get size() {return this.customSize;}set size(val) {this.customSize = val;this.style.width = val + "px";this.style.height = val + "px";}attributeChangedCallback(name,oldVal,newVal) {this.style.background = newVal;console.log(name,oldVal,newVal);}}customElements.define("custom-circle",CustomCircle);function createCus() {let cus = new CustomCircle();document.querySelector("#block").append(cus);}function removeCus() {let cus = document.querySelector(".custom")if (cus)  cus.remove();}function addSize() {let cus = document.querySelector(".custom")if (cus) {cus.size = cus.size + 10;}}function changeColor() {let cus = document.querySelector(".custom")cus.setAttribute("cus","yellow");}</script>

2.1 组件渲染过程

浏览器在解析HTML文档时,当在Web组件还没有定义就遇到其标签时,浏览器会向DOM树中添加一个通用的HTMLElement,即便它们不知道要对它做什么。之后,当自定义元素有定义之后,这个通用元素会被“升级”,从而具备预期的外观与行为。

如果Web组件包含子元素,那么在组件有定义之前它们可能会被不适当地显示出来。可以使用下面的CSS将Web组件隐藏到它们有定义为止。(:not(:defined))。

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<cus-ele><span>hello</span>
</cus-ele>
<cus-ele class="cus"><span>hello</span>
</cus-ele>
</body>
</html><style>
.cus:not(:defined) {opacity: 0;
}
</style>

3 影子DOM

Shadom DOM为封装而生,它可以让一个组件拥有自己的“影子”DOM树,这个DOM树不能在主文档中被任意访问,可能拥有局部样式规则,还有其他特性。

3.1 在浏览器中查看组件的影子DOM

浏览器在内部使用DOM/CSS来绘制影子DOM,这个DOM结构一般对用户是隐藏的,但我们可以开发者工具中看见它。在Chrome中,需要打开“Show user agent shadow DOM”选项。

图 <video>标签的影子DOM

我们不能使用一般的JS调用或者选择器来获取shadow DOM 元素,它们不是常规的子元素,而是一种封装手段。

3.2 为元素添加影子DOM

影子DOM允许把一个“影子根节点”附加给一个常规的HTML元素(或自定义元素),后者被称为“影子宿主”(shadow host)。

attachShadow方法是为常规元素附加一个影子根节点,其参数为一个ShadowRootInit类型的对象,其返回一个影子根节点。

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<div class="block"></div>
</body>
</html><script>class CustomEle extends HTMLElement {connectedCallback() {this.style.display = "block";this.style.width = "100px";this.style.height = "100px";this.style.border = "solid black 1px";let shadow = this.attachShadow({mode: 'closed'})shadow.innerHTML = "<div>hello shadow</div>"}}customElements.define("custom-ele",CustomEle);let cus = new CustomEle();document.querySelector(".block").append(cus);console.log(cus.shadowRoot); //如果mode 为open则有值,否则为空
</script>

3.2.1 影子DOM封装

1,在创建影子根节点并将其附加于影子宿主时,可以指定其模式开放还是关闭,关闭的影子根节点将被完全封闭,不可访问。如果开放,意味着影子宿主会有一个shadowRoot属性,js可以通过这个属性来访问影子根节点元素。

2,影子根节点下定义的样式不会影响外部的阳光DOM元素,类似地,影子宿主元素的阳光DOM样式也不会影响影子根节点。

3,影子DOM中发生的某些事件(如”load”)会被封闭在影子DOM中,另一些事件,如focus、mouse和键盘事件则会向上冒泡,穿透影子DOM。当一个发源于影子DOM内的事件跨过边界向阳光DOM传播时,其target属性会变成影子宿主元素。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/161801.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

15 款 PDF 编辑器帮助轻松编辑、合并PDF文档

PDF 编辑器在当今的数字环境中至关重要&#xff0c;因为 PDF 已成为共享和存储信息的首选格式。只需几分钟&#xff0c;可靠的 PDF 编辑器即可让用户能够根据其特定需求修改、定制和定制文档。在本文中&#xff0c;我们全面汇编了 15 款最佳免费 PDF 编辑器&#xff0c;让您可以…

JAVA应用中线程池设置多少合适?

目录 1、机器配置&#xff1a; 2、核心线程数 3、最大线程数多少合适&#xff1f; 4、理论基础 5、测试验证 一个线程跑满一个核心的利用率 6个线程 12 个线程&#xff1a;所有核的cpu利用率都跑满 有io操作 6、计算公式 7、决定最大线程数的流程&#xff1a; 1、机器…

【JavaScript】零碎知识点总结_2

1. 引入网站图标 可以直接放在根目录 还可以 link 引入&#xff08;推荐&#xff09; <linkrel"shortcut icon"href"./assets/favicon.ico"type"image/x-icon">2. 转换为数字 123 -> 123 除 做字符串拼接&#xff0c;算术运算符都…

中国移动发布《新型智慧城市白皮书》(2023版)

加gzh“大数据食铁兽”&#xff0c;回“20231101”&#xff0c;获取材料完整版 导读 通过本系列白皮书&#xff0c;我们系统的阐述了中国移动对中国智慧城市发展趋势&#xff0c;并对中国移动服务智慧城市建设六大核心能力进行了介绍&#xff0c;详细说明了中国移动智慧城市…

强化学习中策略的迭代

一、策略迭代 一旦使用vπ改善了策略π&#xff0c;产生了更好的策略π0&#xff0c;我们就可以计算vπ0并再次对其进行改进&#xff0c;产生更好的π00。因此&#xff0c;我们可以获得一系列单调改善的策略和值函数&#xff1a; 其中E−→表示策略评估&#xff0c;I−→表示策…

07 点积

点积 基本运算几何解释投影运算和基本运算的联系多维空间到一维空间的投影 点积的作用 这是关于3Blue1Brown "线性代数的本质"的学习笔记。 基本运算 两个维数相同的向量 [ 2 , 7 , 1 ] T , [ 8 , 2 , 8 ] T [2, 7, 1]^{T},[8, 2, 8]^{T} [2,7,1]T,[8,2,8]T,求它们…

跟着Nature Communications学作图:纹理柱状图+添加显著性标签!

&#x1f4cb;文章目录 复现图片设置工作路径和加载相关R包读取数据集数据可视化计算均值和标准差方差分析组间t-test 图a可视化过程图b可视化过程合并图ab 跟着「Nature Communications」学作图&#xff0c;今天主要通过复刻NC文章中的一张主图来巩固先前分享过的知识点&#…

D-Link监控账号密码信息泄露

访问漏洞的 url 为 /config/getuser?index0其中泄露了账号密码 使用泄露的账号密码登陆系统 文笔生疏&#xff0c;措辞浅薄&#xff0c;望各位大佬不吝赐教&#xff0c;万分感谢。 免责声明&#xff1a;由于传播或利用此文所提供的信息、技术或方法而造成的任何直接或间接的…

47基于matlab的水印提取,将水印和载体进行图像融合

基于matlab的水印提取&#xff0c;将水印和载体进行图像融合&#xff0c;成为一体&#xff0c;可对合成图像进行加噪处理&#xff0c;剪切处理&#xff0c;小波压缩处理&#xff0c;旋转处理等操作&#xff0c;最后对合成图像实现水印提取&#xff0c;程序已调通&#xff0c;可…

排序——冒泡排序

冒泡排序的基本思想 从前往后&#xff08;或从后往前&#xff09;两两比较相邻元素的值&#xff0c;若为逆序&#xff08;即 A [ i − 1 ] < A [ i ] A\left [ i-1\right ]<A\left [ i\right ] A[i−1]<A[i]&#xff09;&#xff0c;则交换它们&#xff0c;直到序列…

Web前端—网页制作(以“学成在线”为例)

版本说明 当前版本号[20231105]。 版本修改说明20231105初版 目录 文章目录 版本说明目录day07-学成在线01-项目目录02-版心居中03-布局思路04-header区域-整体布局HTML结构CSS样式 05-header区域-logo06-header区域-导航HTML结构CSS样式 07-header区域-搜索布局HTML结构CSS…

PostgreSQL manual

set path D:\DB\PostgreSQL\16\binconnect to database –h is host name -p is port number -d is database name -U is for user name psql -h localhost -p 5432 -d postgres -U postgres查詢版本信息 select version(); PostgreSQL 8.4.20 on x86_64-redhat-linux-gnu, …