ShadyCSS polyfill无法正确处理Edge中的CSS

问题描述 投票:8回答:1

我正在为第三方网站构建一个小部件,使用影子DOM来防止其CSS干扰我们的CSS。我正在使用ShadyDOMShadyCSS填充来使其在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元素。已经使用(divbutton等)而不是提出自己的元素或模板,但是如果愿意的话,我愿意考虑模板和/或自定义元素,而无需必须进行很多大更改。

javascript shadow-dom polyfills shady-dom
1个回答
7
投票

With 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将用div替换:host并将其添加为全局样式,所以如果您有另一个与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>
© www.soinside.com 2019 - 2024. All rights reserved.