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

Eli*_*ria 8 javascript web-component polyfills shadow-dom shady-dom

我正在为第三方网站构建一个小部件,使用影子DOM来防止其CSS干扰我们的CSS。我正在使用ShadyDOMShadyCSS polyfills使它在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>
Run Code Online (Sandbox Code Playgroud)

In Chrome (which supports shadow DOM natively), the stuff div has a pink background, as I would expect. But in Edge (which does not support shadow DOM natively), I see the "stuff inside shadow dom" text (meaning my script ran and the ShadyDOM functions worked), but I don't see the pink background.

Why is this happening? I am attaching a shadow root to a plain old div, instead of using custom elements as the example in the ShadyCSS README does, but does that matter? If so, how can I make this work? I am working on a big, existing app, and not wanting to make too many changes at once, so I would strongly prefer to use the standard HTML elements I am already using (divs, buttons, etc.) instead of coming up with my own elements or templates, although I would be willing to consider templates and/or custom elements if it can be done easily, without having to make a lot of big changes.

Sup*_*arp 7

使用ShadyCSS

:host Edge中不知道CSS伪元素。

要使其工作,您应该使用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) )
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)

注意:由于polyfill会将:host替换为div并将其添加为全局样式,因此如果您有另一个匹配的HTML代码部分,则可能会看到一些副作用div .stuff


没有ShadyCSS

ShadyCSS专为自定义元素而设计,但并非真正为标准元素设计的。但是,您应该从polyfill中获取灵感,并为假(polyfilled)Shadow DOM显式创建样式属性。在您的情况下,请替换:hostdiv#containter

container.attachShadow( { mode: "open" } )
         .appendChild( tpl.content.cloneNode(true) )
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)