Eli*_*ria 8 javascript web-component polyfills shadow-dom shady-dom
我正在为第三方网站构建一个小部件,使用影子DOM来防止其CSS干扰我们的CSS。我正在使用ShadyDOM和ShadyCSS 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.
使用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显式创建样式属性。在您的情况下,请替换:host为div#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)