本文转载自微信公众号「编程三昧」,作者隐逸王 。转载本文请联系编程三昧公众号。
前言
通过前面的学习,对自定义组件的相关概念和知识点也有了一定了解,今天我们就来学习一下给自定义元素及其子元素设置样式的几种方法。
直接给自定义标签添加样式
index.html:
<style>
my-card{
display: block;
margin: 20px;
width: 200px;
height: 200px;
border: 3px solid #000;
}
</style>
<my-card></my-card>
<script src="./index.js"></script>
index.js:
class MyCard extends HTMLElement {
constructor() {
super();
this.shadow = this.attachShadow({ mode: "open" });
}
}
window.customElements.define("my-card", MyCard);
结果样式生效:
需要注意的是:继承自 HTMLElement 的自定义元素,其 style.display 默认为 inline。
由以上结果可以推论出:
- 给自定义元素添加 class,然后通过 class 名称设置样式可以生效;
- 给自定义元素添加行内样式,可以生效;
- 在自定义元素构造函数中给 this 添加样式,可以生效。
给自定义元素内部子元素设置样式
在主 DOM 通过类名设置
在 style 标签中增加如下样式:
<style>
my-card {
display: block;
margin: 20px;
width: 200px;
height: 200px;
border: 3px solid #000;
}
.card-header {
padding: 10px;
font-weight: bold;
background-color: yellow;
}
</style>
<my-card></my-card>
<script>
class MyCard extends HTMLElement {
constructor () {
super();
this.shadow = this.attachShadow({mode: "open"});
let headerEle = document.createElement("div");
headerEle.className = "card-header";
headerEle.innerText = "My Card";
this.shadow.appendChild(headerEle);
}
}
window.customElements.define("my-card", MyCard);
</script>
结果:不生效。
通过前面的学习,我们知道:自定义元素内部实际上是一个 Shadow DOM,它和主 DOM 是相互隔离的,所以,主 DOM 中的样式是影响不到 Shadow DOM 的。
使用 JS 给 Shadow DOM 增加 style 标签
这里分为两种场景:在主 DOM 使用 JS 、在 Custom Elements 构造函数中使用 JS。
第一种:在主 DOM 使用 JS 给 Shadow DOM 增加 style 标签:
<style>
my-card {
display: block;
margin: 20px;
width: 200px;
height: 200px;
border: 3px solid #000;
}
</style>
<my-card>
</my-card>
<script>
class MyCard extends HTMLElement {
constructor () {
super();
this.shadow = this.attachShadow({mode: "open"});
let headerEle = document.createElement("div");
headerEle.className = "card-header";
headerEle.innerText = "My Card";
this.shadow.appendChild(headerEle);
}
}
window.customElements.define("my-card", MyCard);
// 给 Shadow DOM 增加 style 标签
let styleEle = document.createElement("style");
styleEle.textContent = `
.card-header{
padding:10px;
background-color: yellow;
font-size: 16px;
font-weight: bold;
}
`;
document.querySelector("my-card").shadowRoot.appendChild(styleEle);
</script>
效果如下:
第二种:在 Custom Elements 构造函数中使用 JS 增加 style 标签:
<style>
my-card {
display: block;
margin: 20px;
width: 200px;
height: 200px;
border: 3px solid #000;
}
</style>
<my-card>
</my-card>
<script>
class MyCard extends HTMLElement {
constructor () {
super();
this.shadow = this.attachShadow({mode: "open"});
let styleEle = document.createElement("style");
styleEle.textContent = `
.card-header{
padding:10px;
background-color: yellow;
font-size: 16px;
font-weight: bold;
}
`;
this.shadow.appendChild(styleEle);
let headerEle = document.createElement("div");
headerEle.className = "card-header";
headerEle.innerText = "My Card";
this.shadow.appendChild(headerEle);
}
}
window.customElements.define("my-card", MyCard);
</script>
效果如下:
就以上两种方式来说,第二种更符合组件化的特征,并且使用第一种方式时要注意,如果将添加 style 标签的代码放在定义 Custom Elements 之前会报错(找不到自定义元素)。
引入 CSS 文件
这里使用 JS 创建 link 标签,然后引入 CSS 文件给自定义元素内部的子元素设置样式,代码如下:
<style>
my-card {
display: block;
margin: 20px;
width: 200px;
height: 200px;
border: 3px solid #000;
}
</style>
<my-card>
</my-card>
<script>
class MyCard extends HTMLElement {
constructor () {
super();
this.shadow = this.attachShadow({mode: "open"});
let linkEle = document.createElement("link");
linkEle.rel = "stylesheet";
linkEle.href = "./my_card.css";
this.shadow.appendChild(linkEle);
let headerEle = document.createElement("div");
headerEle.className = "card-header";
headerEle.innerText = "My Card";
this.shadow.appendChild(headerEle);
}
}
window.customElements.define("my-card", MyCard);
</script>
my_card.css 代码如下:
.card-header{
padding:10px;
background-color: yellow;
font-size: 16px;
font-weight: bold;
}
效果如下:
当然,这里也可以在主 DOM 中使用 JS 给 Shadow DOM 引入 CSS 文件,但是,这样做不符合组件化的特征,所以略过。
结束语
以上就是给自定义元素及其子元素进行样式设置的基本方法总结。
~