Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/css/40.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2008/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Css 如何在Google Chrome扩展中真正隔离样式表?_Css_Google Chrome Extension_Isolation - Fatal编程技术网

Css 如何在Google Chrome扩展中真正隔离样式表?

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方便

我写了一个GoogleChrome扩展,它弹出一个带有自动完成字段的对话框,它有自己的风格,但是有些网站我的CSS完全被破坏了,这看起来不太好

我知道用iFrame隔离样式,但在GoogleChrome扩展中,没有办法用这种方式隔离HTML和CSS。另一种方法是将我的所有内容包装到一个单独的div中,其中包含它自己的id和该id的相对样式,我这样做了,但是在一些带有“硬”标记样式重载或CSS代码中的“!important”指令的站点上,它似乎不起作用

所以,我想知道是否有任何方法可以真正以z方便的方式隔离我的样式,或者我的坏习惯是重载每个CSS属性来修复每个站点的一个或另一个样式问题


顺便说一句:我将清单设置为在“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;
}