Css 如何在Google Chrome扩展中真正隔离样式表?
我写了一个GoogleChrome扩展,它弹出一个带有自动完成字段的对话框,它有自己的风格,但是有些网站我的CSS完全被破坏了,这看起来不太好 我知道用iFrame隔离样式,但在GoogleChrome扩展中,没有办法用这种方式隔离HTML和CSS。另一种方法是将我的所有内容包装到一个单独的div中,其中包含它自己的id和该id的相对样式,我这样做了,但是在一些带有“硬”标记样式重载或CSS代码中的“!important”指令的站点上,它似乎不起作用 所以,我想知道是否有任何方法可以真正以z方便的方式隔离我的样式,或者我的坏习惯是重载每个CSS属性来修复每个站点的一个或另一个样式问题Css 如何在Google Chrome扩展中真正隔离样式表?,css,google-chrome-extension,isolation,Css,Google Chrome Extension,Isolation,我写了一个GoogleChrome扩展,它弹出一个带有自动完成字段的对话框,它有自己的风格,但是有些网站我的CSS完全被破坏了,这看起来不太好 我知道用iFrame隔离样式,但在GoogleChrome扩展中,没有办法用这种方式隔离HTML和CSS。另一种方法是将我的所有内容包装到一个单独的div中,其中包含它自己的id和该id的相对样式,我这样做了,但是在一些带有“硬”标记样式重载或CSS代码中的“!important”指令的站点上,它似乎不起作用 所以,我想知道是否有任何方法可以真正以z方便
顺便说一句:我将清单设置为在“document_end”加载所有内容,但我发现它没有应用于每次DOM就绪时加载的样式表。使用iframes。这是一个解决办法,但效果很好
Maxime已经写了一篇文章。在提出这个问题时,您唯一的选择是使用iFrame,或者使用具有非常高优先级的样式表,并显式设置所有可能影响样式的属性。最后一种方法非常麻烦,因为总会有一些属性被您忽略。因此,隔离样式表的唯一可用方法是使用iframe
这个问题的解决方案是(在没有iframe的情况下隔离样式)。你可以在上找到教程。对于使用Shadow DOM隔离样式的真实Chrome扩展,请参见()。由于我最近经历了本期的挑战,我想分享一些我认为有价值的信息 首先,Rob W的答案是正确的。shadowdom是这个问题的正确解决方案。然而,在我的例子中,我不仅需要CSS隔离,还需要JavaScript事件。例如,如果用户单击位于孤立HTML中的按钮,会发生什么情况?这在使用影子DOM时会变得非常糟糕,但我们有另一种Web组件技术,即自定义元素来拯救它。除了在撰写本文时,chrome中有一个bug阻止了chrome扩展中的自定义元素。请参阅我的问题和 那我们该怎么办?我相信今天最好的解决方案是IFrames,这就是我所使用的。shahalpk linked这篇文章很棒,但它只描述了过程的一部分。我是这样做的: 首先,为您的独立小部件创建一个html文件和js文件。这些文件中的所有内容都将在iframe中的隔离环境中运行。确保您的js文件源于html文件
//iframe.js
var button = document.querySelector('.my-button');
button.addEventListener('click', function() {
// do useful things
});
//iframe.html
<style>
/* css */
</style>
<button class='my-button'>Hi there</button>
<script src='iframe.js'></script>
就这样
要记住一件事:如果需要在iframe和内容脚本的其余部分之间进行通信,则需要将chrome.runtime.sendMessage()切换到后台页面,然后将chrome.tabs.sendMessage从后台页面切换回选项卡。他们不能直接沟通
编辑:我写了一篇博客文章,详细介绍了我在这个过程中学到的一切,包括一个完整的chrome扩展示例和许多指向不同信息的链接:
如果我的博客被删除,以下是原始帖子的来源:
我最近创建了Boundary,一个CSS+JS库来解决类似的问题。Boundary创建的元素与现有网页的CSS完全分离 以创建对话框为例。安装Boundary后,可以在内容脚本中执行此操作
var dialog=Boundary.createBox(“yourDialogID”、“yourDialogClassName”);
Boundary.loadBoxCSS(“yourDialogID”,“dialog.css中元素的样式”);
边界附加框(
“#yourDialogID”,
“提交”
);
边界。查找(“提交”按钮)。单击(函数(){
//点击按钮后的一些js。
});
#yourDialogID中的元素将不受现有网页的影响。函数的作用是:返回一个常规的jQuery DOM元素,以便您可以使用它执行任何操作
希望这有帮助。如果你有任何问题,请告诉我
要么使用all
或者使用阴影DOM
图书馆
用法
你已经试过了吗?两者的结合应该足够了。确保您的选择器足够具体。谢谢Rob!是的,我试过了,但似乎并不适用于每个网站。我知道即使我在CSS中设置“Computed style”(在GC DevTools中)时显示所有内容的页面,例如“list style:none!important;”,它仍然会继续向我显示带有“disc”标记的列表。而且,是的,我的风格在清单中设置,就像在你的建议中一样,它通过在DOM创建后嵌入到头部来加载Dynamicly。也许有别的方法可以在谷歌Chrome扩展中隔离样式?我是指清单中的“禁用继承:打开”选项之类的秘密?我最后的建议如何?增加选择器的数目。如果您控制要设置样式的元素,则添加
style=“prop:val!important”
将具有最高优先级-例如,请参阅。请参阅我对类似问题的回答:。有几种方法,但我详细介绍的方法可能是最简单、最可靠的…:)Display#Anchors
扩展非常方便(例如,用于链接到Chrome扩展文档的特定部分;))也可以使用Sass,如:#myid{.myextension styles…}
来解决这个问题。很好!现在这是一个更好的答案。(虽然你应该去掉snippet标签,但它没有用)@Xan这是我第一次在stackoverflow上发布答案,所以非常感谢你的指导!这能很好地响应用户事件吗?当涉及到事件处理时,shadowdom非常棘手。我尝试使用React+shadowdom隔离扩展,但仍然无法绑定eve
var iframe = document.createElement('iframe');
iframe.src = chrome.extension.getURL("iframe.html");
document.body.appendChild(iframe);
.some-selector {
all: initial;
}
.some-selector * {
all: unset;
}
function Widget(nodeName, appendTo){
this.outer = document.createElement(nodeName || 'DIV');
this.outer.className = 'extension-widget-' + chrome.runtime.id;
this.inner = this.outer.createShadowRoot();
(appendTo || document.body).appendChild(this.outer);
}
Widget.prototype.show = function(){
this.outer.style.display = 'block';
return this;
};
Widget.prototype.hide = function(){
this.outer.style.display = 'none';
return this;
};
var myWidget = new Widget();
myWidget.inner.innerHTML = '<h1>myWidget</h1>';
/*
* Reset Widget Wrapper Element
*/
.extension-widget-__MSG_@@extension_id__ {
background: none;
border: none;
bottom: auto;
box-shadow: none;
color: black;
cursor: auto;
display: inline;
float: none;
font-family : "Helvetica Neue", "Helvetica", "Arial", sans-serif;
font-size: inherit;
font-style: normal;
font-variant: normal;
font-weight: normal;
height: auto;
left: auto;
letter-spacing: 0;
line-height: 100%;
margin: 0;
max-height: none;
max-width: none;
min-height: 0;
min-width: 0;
opacity: 1;
padding: 0;
position: static;
right: auto;
text-align: left;
text-decoration: none;
text-indent: 0;
text-shadow: none;
text-transform: none;
top: auto;
vertical-align: baseline;
white-space: normal;
width: auto;
z-index: 2147483648;
}
/*
* Add your own styles here
* but always prefix them with:
*
* .extension-widget-__MSG_@@extension_id__
*
*/
.extension-widget-__MSG_@@extension_id__{
position: fixed;
top: 100px;
margin: 0 auto;
left: 0;
right: 0;
width: 500px;
}
.extension-widget-__MSG_@@extension_id__::shadow h1 {
display: block;
margin: 0 auto;
padding: 20px;
background-color: yellow;
border: 10px solid green;
font-size: 20px;
text-align: center;
}