我正在为第三方网站构建一个小部件,使用影子DOM来防止其CSS干扰我们的CSS。我正在使用ShadyDOM和ShadyCSS填充来使其在Edge和IE中工作,但是它并没有像我期望的那样为影子DOM转换CSS。
示例:
<!DOCTYPE html>
<html>
<head>
<title>Shadow DOM test</title>
</head>
<body>
<div id="container">container is here</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/webcomponentsjs/2.3.0/webcomponents-bundle.js"></script>
<script>
const shadow = document.getElementById("container").attachShadow({ mode: "open" });
const style = document.createElement("style");
style.innerHTML = `
:host .stuff {
background: #ff00ff;
}
`;
shadow.appendChild(style);
const div = document.createElement("div");
div.classList.add("stuff");
div.innerHTML = "stuff inside shadow dom";
shadow.appendChild(div);
</script>
</body>
</html>
在Chrome(本机支持影子DOM)中,stuff
div具有粉红色的背景,正如我所期望的那样。但是在Edge(本机不支持影子DOM)中,我看到了“影子dom内的东西”文本(表示我的脚本已运行并且ShadyDOM函数正常工作),但看不到粉红色的背景。
为什么会这样?我将影子根附加到普通的旧div上,而不是像ShadyCSS README中的示例那样使用自定义元素,但这有关系吗?如果是这样,我该如何进行这项工作?,我正在开发一个大型的现有应用程序,并且不想一次进行太多更改,因此我强烈希望使用标准我已经在使用HTML元素(div
,button
等),而不是提出自己的元素或模板,尽管我愿意考虑模板和/或自定义元素(如果可以轻松完成,而无需进行大量更改)。
答案 0 :(得分:7)
使用ShadyCSS
:host
CSS伪元素在Edge中未知。
要使其正常工作,应使用ShadyCSS.prepareTemplate()
,它将用自定义元素的名称替换:host,并将样式定义为将应用于所有页面的全局样式。
请记住,Edge中没有Shadow DOM:具有伪造/填充的Shadow DOM的CSS没有边界/范围。
您可以使用ShadyCSS.prepareTemplate( yourTemplate, 'div' )
,如下例所示:
ShadyCSS.prepareTemplate( tpl, 'div' )
container.attachShadow( { mode: "open" } )
.appendChild( tpl.content.cloneNode(true) )
<script src="https://cdnjs.cloudflare.com/ajax/libs/webcomponentsjs/2.3.0/webcomponents-bundle.js"></script>
<template id=tpl>
<style>
:host .stuff {
background: #ff00ff;
}
</style>
<div class=stuff>stuff inside shadow dom</div>
</template>
<div id=container>container is here</div>
注意:,因为polyfill将:host替换为div并将其添加为全局样式,所以如果您有另一个与div .stuff
相匹配的HTML代码部分,则可能会看到一些副作用。
没有ShadyCSS
ShadyCSS是为自定义元素而设计的,但并不是为标准元素而设计的。但是,您应该从polyfill中获取灵感,并为假(polyfilled)Shadow DOM显式创建样式属性。在您的情况下,将:host
替换为div#containter
:
container.attachShadow( { mode: "open" } )
.appendChild( tpl.content.cloneNode(true) )
<script src="https://cdnjs.cloudflare.com/ajax/libs/webcomponentsjs/2.3.0/webcomponents-bundle.js"></script>
<template id=tpl>
<style>
div#container .stuff {
background: #ff00ff;
}
:host .stuff {
background: #ff00ff;
}
</style>
<div class=stuff>stuff inside shadow dom</div>
</template>
<div id=container>container is here</div>