css中的1px以及图片模糊
webComponent ⭐ 什么是Web组件? Web组件(Web Components)是一种用于创建可重用的自定义HTML元素的技术。它们是Web开发的一项重要标准,旨在改善Web应用程序的可维护性、可复用性和封装性。Web组件允许开发者创建自定义HTML标签,具有其自己的样式、行为和功能,然后将它们在不同页面和项目中重复使用。
Web组件的核心思想是将Web应用程序拆分为小而独立的部分,每个部分都可以自定义,然后将这些部分组合在一起以构建复杂的Web应用程序。这有助于降低代码的复杂性,提高代码的可维护性,同时促进团队合作和组件的共享。
⭐ Web组件的主要部分 Web组件由几个主要部分组成,每个部分都有其独特的作用:
自定义元素(Custom Elements): 自定义元素是Web组件的核心,它们是开发者定义的自定义HTML标签。自定义元素可以包含自己的样式、DOM结构和JavaScript行为。它们通过JavaScript的CustomElementRegistry API注册,并在HTML中使用。
Shadow DOM(影子DOM): Shadow DOM 允许你将组件的样式和DOM树封装在一个独立的、隔离的DOM子树中。这样,组件的样式和DOM结构不会受到外部CSS样式的污染,并且不会影响到外部DOM。Shadow DOM使用
HTML模板(HTML Templates): HTML模板是一种定义组件内部DOM结构的机制。它允许你在组件内部定义一段标记,但不会在页面加载时立即渲染。相反,你可以在需要时通过JavaScript将模板内容克隆到Shadow DOM中,以实现动态渲染。
HTML导入(HTML Imports): HTML导入是一种将多个Web组件打包到单个HTML文件中的机制。这有助于将组件封装为可重用的单元,以便在多个项目中共享。不过,HTML导入规范目前已经被废弃,现在通常使用ES6模块或其他构建工具来导入组件。
Web组件提供了一种清晰的方式来封装、隔离和重用前端代码,有助于创建可维护和可扩展的Web应用程序。虽然Web组件是Web标准的一部分,但在所有浏览器中都得到了广泛支持,使其成为现代Web开发中的有力工具。 ⭐示例:
<!-- 示例1:自定义元素的注册 -->
<!DOCTYPE html>
<html>
<head>
<title>Web组件示例</title>
</head>
<body>
<!-- 注册自定义元素 -->
<script>
class MyComponent extends HTMLElement {
constructor() {
super();
// 在构造函数中创建Shadow DOM
const shadow = this.attachShadow({ mode: 'open' });
// 创建一个span元素并将其添加到Shadow DOM中
const span = document.createElement('span');
span.textContent = 'Hello, Web Component!';
shadow.appendChild(span);
}
}
// 注册自定义元素
customElements.define('my-component', MyComponent);
</script>
<!-- 使用自定义元素 -->
<my-component></my-component>
</body>
</html>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
上述示例中,我们首先创建了一个自定义元素MyComponent,并在构造函数中创建了一个Shadow DOM。然后,我们将一个元素添加到Shadow DOM中,并将其包含的文本设置为"Hello, Web Component!"。最后,通过customElements.define方法将自定义元素注册到浏览器中,并在HTML中使用它。
这个示例演示了如何创建一个简单的自定义元素,并将其添加到页面中。
<!-- 示例2:使用HTML模板 -->
<!DOCTYPE html>
<html>
<head>
<title>Web组件示例</title>
</head>
<body>
<!-- 定义一个HTML模板 -->
<template id="my-template">
<style>
span {
color: blue;
}
</style>
<span>Hello from template!</span>
</template>
<!-- 使用HTML模板 -->
<script>
// 获取模板内容
const template = document.getElementById('my-template');
// 克隆模板内容
const clone = document.importNode(template.content, true);
// 将模板内容添加到页面
document.body.appendChild(clone);
</script>
</body>
</html>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
在这个示例中,我们定义了一个包含样式和DOM结构的HTML模板。然后,我们使用JavaScript获取模板内容,通过document.importNode方法克隆模板内容,并将其添加到页面中。这样,我们可以动态地插入模板内容,实现自定义组件的动态渲染。 这些代码示例演示了Web组件的一些基本概念,包括自定义元素、Shadow DOM和HTML模板的使用。希望这些示例对你理解Web组件有所帮助。
系列文章:https://cloud.tencent.com/developer/user/8730813/articles
我们可以使用slot去完成样式和内容的灵活控制。使用slot去替换sytle不支持。sytle上使用slot无效。
web component不受任何框架限制,因为是浏览器原生就支持。所以可以在vue、react里使用:https://blog.csdn.net/A1215383843/article/details/139308121
我们可以利用web component本身自有的生命周期去监听属性的变化达到数据的监听。进而完成数据响应式效果。
每个 web component 都有一个shadow dom,每个shadow dom可以被认为是一个新的document文档,所以做到了css、html、js隔离的效果,每个web component 就行框架里的组件一样,独立且可重复使用。
我们可以在 webcomponent里面去解析html字符串为元素,这样就避免把template元素写在web component里面,就非常干净了。如下:
// 创建一个HTML字符串. const htmlString = "<div><p>Hello, World!</p></div>"; // 使用DOMParser解析HTML字符串 const parser = new DOMParser(); // parser.parseFromString(htmlString, "text/html")拿到的是document对象 const doc = parser.parseFromString(htmlString, "text/html").body.children[0]; // 注意:如果htmlString的最外层是template元素那么arser.parseFromString(htmlString, "text/html")的值为undefined。这个template元素不属于document特性有关。 可以一试,瑞国成功,那么元素就不用写在页面里面了,直接写在自定义的元素里面,很简洁:可以试一下先创建template元素,然后使用innerHTML把字符串塞入template里面,字符串就自动转为node了。或者直接在shadow dom 上直接使用innerHMTL直接传入字符串看行不行(slot元素也直接写在里面方便控制样式和内容)。1
2
3
4
5
6
7
8
9
10
11
12
13
自己封装了web component 的使用方法,按早下面的方式,只要引入js即可直接在页面使用自定义元素
// 自定义一个web component class MyCard extends HTMLElement { static get observedAttributes() { return ["style"]; // 需要监听的属性列表 // 配合下面的attributeChangedCallback生命周期使用。 } constructor() { // 挂载内容 super(); this.shadow = this.attachShadow({ mode: "open" }); const template = document.createElement("template"); // 组件内容,包括了slot占位符,已经默认样式 template.innerHTML = ` <style> * { box-sizing: border-box; } :host { display: block; } .info-row { display: flex; padding-top: 15px; } .info-column { display: flex; align-items: center; } .info-title { padding: 0 10px; color: #0e5bd3; font-size: 12px; word-break: keep-all; } .info-content { letter-spacing: 2px; } </style> <style id="custom"></style> <div class="info-row bg"> <div class="info-column"> <div class="info-title">姓名</div> </div> <div class="info-content"> <slot name="userName">隐逸王</slot> </div> </div> `; // 把内容插入 shadow dom里面 this.shadow.appendChild(document.importNode(template.content, true)); } updateStyle(elem, value) { const shadow = elem.shadowRoot; shadow.getElementById("custom").textContent = value; } attributeChangedCallback(name, oldValue, newValue) { this.updateStyle(this, newValue); } } // 注册自定义元素以便直接在html里使用 customElements.define("my-card", MyCard); // 业务逻辑代码:2秒后元素的背景色会被替换,以及名字会被没替换。 setTimeout(() => { // document.querySelector("my-card").updateStyle // 可以访问web component里面自定义的方法 document.querySelector("my-card").setAttribute("style", ".bg {background-color: #999;}"); document.getElementById("name").innerHTML = "比克大魔王"; // 这样做也可以实现内容的更新 // 总结:关于样式的更新,我们只能是通过变化属性值的方式去设置,无法通过slot的方式去设置。内容的更新,我们可以通过属性值的方式去更新(哥style一样),;还可以通过slot的方式去更新。 }, 2500); // 注意:我们可以借助proxy的能力去把值的变化和组件的更新关联起来,这样就可以实现更加的自动化。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74<my-card style=" .bg { background-color: red; } " > <!-- 替换里面的内容:指定插槽时可以替换里面的默认内容 --> <span id="name" slot="userName">编程三昧哈哈</span> </my-card>1
2
3
4
5
6
7
8
9
10