书接上文,上一篇博客。让我们对影子模型有了大致的了解并且可以修改其样式!现在,我们自己去写一个自己的组件!
同样是利用shadow-DOM。首先,我们准备基本的html,也就是我们前面说的 shadow-host
<div id="host">
Sorry! Your browser does not support the shadow-DOM!!!
div> //我是宿主
为了友好提示!我们加一句 “Sorry! Your browser does not support the shadow-DOM!!!”
接下来就是javascript了
if(document.body.createShadowRoot){
var host = document.querySelector('#host');
var root = host.createShadowRoot();
root.innerHTML = 'Shadow-DOM!!!
'
}
让我们看看效果: 上面是chrome浏览器支持shadow-DOM显示效果。底下是不支持的safari显示效果。
试想如果我们如何去改变h1的颜色呢?
.h1{
background: red;
}
#host::test{
background: red;
}
无论是利用类名选择器这样是行不通的。还是借鉴浏览器自带的伪类选择器的方法,都是行不通的。
注意了:因为影子宿主和影子根之间存在影子边界(shadow boundary)所以,主DOM的样式是不会影响到shadow-DOM,同样shadow-DOM的样式也不能影响到主DOM。
在这里顺便扯一句: 我感觉有点想vue里面的 给组件的css加上scope一样。
那我们要怎么才能自定义影子模型的样式呢?
我们需要借助content和 template 为了直观,还是先上代码:
<html lang="en">
<head>
<meta charset="UTF-8">
<title>shadowDOMtitle>
head>
<body>
<div id="host">
<h1 class="title">I am titleh1>
<p class="subtitle">I am subtitlep>
div>
<template id="temp">
<style>
span{
color: red;
}
style>
<p>shadowDOMp>
<span>I'm the span tag of templatespan>
<content select=".title">content>
template>
<script>
var host = document.querySelector('#host');
var root = host.createShadowRoot();
var temp = document.querySelector('#temp');
var clone = document.importNode(temp.content, true);
root.appendChild(clone);
script>
body>
步骤:
::content h1{
background: red;
}
::content p{
background: green;
}
/*对宿主对象进行css设置*/
:host{
border: 2px solid #ccc;
transition: 200ms;
}
/*定义宿主的hover*/
:host(:hover){
padding: 20px;
}
如果你觉的在template标签里面写css样式不够好的话!我没可以借助 ::shadow(只能作用于shadow-root下面的内容) /deep/(可以作用于shadow-root下面的content里面的内容)
#host::shadow p{
color: pink;
}
/*只能穿透一层*/
#host /deep/ p{
color: blue;
}
至此!关于shadow-dom的自定义shadow-dom的样式就告一段落了。接下来我们再来学习关于他的事件。
document.addEventListener('click', function(e) {
console.log(e.target.innerHTML + ' click!');
});
可以看出shadow-DOM的事件全部绑定到了宿主对象上面。避免破坏主DOM的事件。
至于content里面的内容,因为他在文档中有真实的DOM节点。所以没有没有重定向到宿主上面。
细心的童鞋,不难发现宿主的事件没有发生冒泡!以下是代码,大家可以分别点击红色的div和宿主看看弹出内容的所弹出的次数。如果你嫌弃麻烦请看图:
<html lang="en">
<head>
<meta charset="UTF-8">
<title>shadowDOMtitle>
head>
<body>
<style>
#pop{
width: 200px;
height: 200px;
background-color: red;
}
style>
<div id="pop">点我会冒泡 出现2次clickdiv>
<div id="host">
<h1 class="title">I am titleh1>
<p class="subtitle">I am subtitlep>
div>
<template id="temp">
<style>
span{
color: red;
}
style>
<p>shadowDOMp>
<span>I'm the span tag of templatespan>
<content select=".title">content>
template>
<script>
var host = document.querySelector('#host');
var pop = document.querySelector('#pop');
var root = host.createShadowRoot();
var temp = document.querySelector('#temp');
var clone = document.importNode(temp.content, true);
root.appendChild(clone);
document.addEventListener('click', function(e) {
console.log(e.target.innerHTML + ' click!');
});
pop.addEventListener('click', function(e) {
console.log(e.target.innerHTML + ' click!');
});
script>
body>