快乐的时光都是这么短暂,转眼间,web原生组件的知识点已经学完了,这个虽然暂时不一定有用,但是随着时间的积累,一步一个脚印的积累,你会有相应的收获,希望能变得更强,比如两年前我也会想有现成的东西不用,干嘛要自己写呢?但是你确定一直用上层的东西,你的收获有自己写快吗? 在开发的过程过能节约下来的时间,我们可以用这个时间拿来学习,这样随着时间的积累我们会变得更强,也会慢慢有更多的时间投入生活,进行正向循环

css问题

自定义元素然后是普通的HTML元素,也可以使用css设置样式

在我们没有设置shadow DOM的组件,进行全局样式设置

<app-element></app-element>

<style>
/* CSS Global */
app-element {
display: inline-block;
padding: 6px 20px;
background: steelblue;
color: white;
}
app-element span {
font-weight: bold;
vertical-align: super;
font-size: small;
color: gold;
}
</style> <script>
customElements.define("app-element", class extends HTMLElement {
connectedCallback() {
this.innerHTML = `<div class="element">AppElement <span>New!</span></div>`;
}
});
</script>
  • 无论文档是否具有Shadow DOM,都可以从文档的全局CSS从组件外部)对组件本身进行样式设置。
  • 只要没有Shadow DOM可以“保护”组件,就可以对组件中的元素进行全局样式设置

HTML 外部引入

<app-element></app-element>

<script>
customElements.define("app-element", class extends HTMLElement {
connectedCallback() {
this.innerHTML = `
<link rel="stylesheet" href="/components/AppElement.css">
<style>
@import "/components/AppElement.css";
</style>
<div class="element">
AppElement <span>New!</span>
</div>
`;
}
});
</script>

程序化动态的方法

<app-element></app-element>

<script>
import css from "./AppElement.css"; customElements.define("app-element", class extends HTMLElement {
connectedCallback() {
document.adoptedStyleSheets = [...document.adoptedStyleSheets, css];
this.innerHTML = `
<div class="element">
AppElement <span>New!</span>
</div>
`;
}
});
</script>
this.shadowRoot.adoptedStyleSheets = [...document.adoptedStyleSheets, css];

我们通过import 加载css,在这种情况下,它是组件的相对路径,在加载css内容中并生成一个对象cssStyleSheet ,然后通过.adoptedStyleSheets 导入css

这种方法直接使用是错误的,需要引入插件css-loader,应该要借助webpack ,原生不能直接使用

import css from "./AppElement.css"

css自定义属性

var(--color,red)
// 第一个变量不存在,用第二个

全局设置,穿透到里面

<app-element></app-element>
<app-element></app-element>
<app-element></app-element> <style>
/* CSS Global */
app-element:first-of-type {
--color: orangered;
}
</style> <script>
customElements.define("app-element", class extends HTMLElement {
connectedCallback() {
this.innerHTML = `
<style>
/* CSS Local */
.element {
display: inline-block;
padding: 6px 20px;
background: var(--color, steelblue);
color: white;
}
span {
font-weight: bold;
vertical-align: super;
font-size: small;
color: gold;
}
</style>
<div class="element">
AppElement <span>New!</span>
</div>
`;
}
});
</script>

css 作用域

css 伪类,仅在定义了shadow DOM 有效

伪类 描述
:host 它允许我们设置自定义元素(组件自己的容器)的样式。
:host(``css) 同上一个,但前提是它与中定义的选择器匹配css
:host-context(``css) 同上,但前提是您有与选择器匹配的父母css
<app-element></app-element>
<app-element disabled></app-element>
<div class="box">
<app-element></app-element>
</div> <script>
customElements.define("app-element", class extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: "open" });
}
connectedCallback() {
this.shadowRoot.innerHTML = `
<style>
:host {
display: inline-block;
padding: 6px 20px;
background: steelblue;
color: white;
}
:host([disabled]) {
background: #aaa;
}
:host-context(.box) {
background: red;
}
span {
font-weight: bold;
vertical-align: super;
font-size: small;
color: gold;
}
</style>
<div class="element">
AppElement <span>New!</span>
</div>
`;
}
});
</script>

修改最外层的盒子的css

影子DOM操作事件

<app-element></app-element>

<script>
customElements.define("app-element", class AppElement extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: "open" });
} sendMessage() {
alert("Hello!");
} connectedCallback() {
this.shadowRoot.innerHTML = "<button>点我!</button>";
this.button = this.shadowRoot.querySelector("button");
this.button.addEventListener("click", () => this.sendMessage());
}
// 离开页面删除事件
disconnectedCallback() {
this.button.removeEventListener("click", () => this.sendMessage());
}
});
</script>

第二种方法

不用addEventListener

      this.button.onclick=()=>this.sendMessage()
// 离开页面删除事件
disconnectedCallback() {
this.button.onclick=null;
}

第三种方法

神奇的handleEvent函数

<app-element></app-element>

<script>
customElements.define("app-element", class extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: "open" });
} handleEvent(event) {
if (event.type === "click"){
console.log(3)
}
} connectedCallback() {
this.shadowRoot.innerHTML = "<button> Press me!</button>";
this.button = this.shadowRoot.querySelector("button");
this.button.addEventListener("click", this);
} disconnectedCallback() {
this.button.removeEvenetListener("click", this);
}
});
</script>

我们发现当我们简单的放置this 浏览器会奇特找到.handleEvent函数,存在就进行处理,这种方法我们可以通过检测event.type,我们可以通过这种方法进行集中处理

自定义事件

选择项 描述
detail 包含我们要传输的所有信息的对象。
bubbles 指示该事件是否应气泡在DOM“到表面”或没有。
composed 指示传播是否可以遍历Shadow DOM
cancelable 指示是否可以使用取消行为.preventDefault()

事件传递冒泡

<div class="box1">
<div class="box2"></div>
</div>
<script>
let box2 = document.querySelector('.box2');
let box1 = document.querySelector('.box1');
box2.addEventListener('click',()=>{
box2.dispatchEvent(
new CustomEvent('messages', {
detail: {
message: 'hello'
},
bubbles:true,
})
)
})
box1.addEventListener('messages',(e)=>{
console.log(333);
console.log(e.detail);
})
</script>

bubbles=true 通过冒泡传递给父级,event.target 拿到dom元素,event.detail 拿到创建事件的数据

默认情况下

<div class="box1">
<div class="box2">
<div class="box3"></div>
</div>
</div>
<script>
let box1 = document.querySelector('.box1');
let box2 = document.querySelector('.box2');
let box3 = document.querySelector('.box3');
box3.addEventListener('click',()=>{
console.log(1);
box3.dispatchEvent(
new CustomEvent('messages', {
detail: {
message: 'hello'
},
bubbles:true,
})
)
})
box2.addEventListener('click',()=>{
console.log(2); })
box1.addEventListener('click',()=>{
console.log(3);
})
</script>

我们发现默认情况下冒泡是从里到外1,2,3

当我们在最外层添加

 box3.addEventListener("messages", (event) => {
console.log(4);
},{capture:true});

我们发现执行的顺序为1,4,2,3

跨组件的通信

组件1发送数据

<first-element></first-element>

  customElements.define("first-element", class extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: "open" });
} handleEvent(event) {
if (event.type === "click") {
const MessageEvent = new CustomEvent("messages", {
detail: {from: "Manz", message: ++this.i},
bubbles: true,
composed: true // 影子
});
this.dispatchEvent(MessageEvent);
}
} connectedCallback() {
this.shadowRoot.innerHTML = `<button>点我</button>`;
this.shadowRoot.querySelector("button").addEventListener("click", this);
}
});

接受传递来的数据

  customElements.define("second-element", class extends HTMLElement {
constructor() {
super();
this.attachShadow({mode: "open"});
} handleEvent(event) {
if (event.type === "messages") {
event.detail.from = "Robot";
const data = event.detail;
this.shadowRoot.innerHTML = `
<div>
From ${data.from}:
<span style="color:red">${data.message}</span>
</div>
`;
}
} connectedCallback() {
this.shadowRoot.innerHTML = `<div>No messages</button>`;
document.addEventListener("messages", this);
}
});

这样想不想两个异步组件之间的通信

最新文章

  1. perl 箭头操作符
  2. [译] EXTENDING JQUERY &ndash; 2.2 A simple plugin
  3. Intent和Intent Filter Context
  4. Matlab的libsvm的安装
  5. javascript encodeURI和encodeURIComponent的比较
  6. [LeetNode]Sort List
  7. Oracle分析函数之FIRST_VALUE和LAST_VALUE
  8. Swagger入门教程
  9. python学习之闭包
  10. Python—装饰器详解
  11. FilenameFilter总结
  12. Ansible入门笔记(1)之工作架构和使用原理
  13. sencha touch 在线实战培训 第一期 第一节
  14. HIVE之 Sqoop 1.4.6 安装、hive与oracle表互导
  15. [转]Loadrunner随机生成15位数字串
  16. virtualbox mac-debian共享文件夹
  17. fabric生产环境代码包发布管理
  18. CSS气泡
  19. Eclipse 菜单
  20. ServletContext结合Servlet接口中的init()方法和destroy()方法的运用----网站计数器

热门文章

  1. Android 自定义Vie 对勾CheckBox
  2. 如何安装eclipse
  3. 066 01 Android 零基础入门 01 Java基础语法 08 Java方法 02 带参有返回值方法
  4. 010 01 Android 零基础入门 01 Java基础语法 02 Java常量与变量 04 变量的三个元素的详细介绍之二——变量类型——即Java中的数据类型
  5. http协议和chrome浏览器
  6. P 4315 月下毛景树
  7. IntelliJ IDEA 调试 Java 8 Stream,实在太香了!
  8. SCOI 2008 【奖励关】
  9. 线上服务的FGC问题排查
  10. 如何修改或新增visual studio 的模板