关键词:
【中文标题】如何真正隔离 Google Chrome 扩展中的样式表?【英文标题】:How to really isolate stylesheets in the Google Chrome extension? 【发布时间】:2012-09-28 19:00:15 【问题描述】:我编写了一个谷歌浏览器扩展程序,它会弹出一个带有自动完成字段的对话框,它有自己的风格,但是在某些网站上我的 CSS 完全被破坏了,看起来不太好。
我知道使用 iFrame 隔离样式,但在 Google Chrome 扩展程序中,无法以这种方式隔离我的 HTML 和 CSS。另一种方法是将我所有的东西包装到一个单独的 div 中,并使用它自己的 id 和该 id 的相对样式,我这样做了,但它似乎不适用于某些具有“硬”标签样式重载或“!重要的”指令在 CSS 代码中。
所以,我想知道有没有什么方法可以真正以方便的方式隔离我的样式,或者重载每个小的 CSS 属性来修复每个站点的一个或另一个样式问题是我的坏事?
顺便说一句:我将清单设置为在“document_end”加载所有内容,但我发现它并没有应用于样式表,而样式表每次都在 DOM 准备好时加载。
【问题讨论】:
你试过these methods吗?两者的结合应该足够了。确保您的选择器足够具体。 谢谢罗伯!是的,我试过这个,但它似乎不适用于每个站点。我知道即使我看到“计算样式”(在 GC DevTools 中)显示的所有页面都是我在 CSS 中设置的,例如“list-style: none !important;”,它仍然会继续向我显示带有“光盘”标记的列表。而且,是的 - 我的样式在清单中设置,就像在您的建议中一样,它是在创建 DOM 后通过嵌入到头部动态加载的。也许还有其他方法可以隔离 Google Chrome 扩展中的样式?我的意思是清单中的一些秘密“禁用继承:开启”选项或类似的东西? 我最后的建议怎么样?增加选择器的specifity。如果您控制要设置样式的元素,则添加style="prop:val!important"
将具有最高优先级 - 例如参见 jsfiddle.net/rytkL。
在此处查看我对类似问题的回答:***.com/questions/10608924/…。有几种方法,但我详细介绍的一种可能是最简单和最可靠的...... :)
【参考方案1】:
由于我最近经历了这个问题的挑战,我想分享一些我认为有价值的信息。
首先,Rob W 的答案是正确的。 Shadow DOM 是解决这个问题的正确方法。然而,就我而言,我不仅需要 CSS 隔离,还需要 JavaScript 事件。例如,如果用户单击位于隔离 HTML 中的按钮会发生什么?仅使用 Shadow DOM 就变得非常丑陋,但我们有另一种 Web 组件技术,自定义元素,可以救援。除了在撰写本文时,chrome 中有一个错误会阻止 chrome 扩展中的自定义元素。请参阅我的问题 here 和 here 和 the bug here。
那么这会给我们带来什么影响呢?我相信今天最好的解决方案是 IFrame,这就是我所采用的。 shahalpk 链接的文章很棒,但它仅描述了该过程的一部分。我是这样做的:
首先,为您的独立小部件创建一个 html 文件和 js 文件。这些文件中的所有内容都将在 iframe 中的隔离环境中运行。请务必从 html 文件中获取您的 js 文件。
//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>
接下来,在您的内容脚本中,在 javascript 中创建一个 iframe 元素。您需要在 javascript 中执行此操作,因为您必须使用 chrome.extension.getURL 才能获取您的 iframe html 文件:
var iframe = document.createElement('iframe');
iframe.src = chrome.extension.getURL("iframe.html");
document.body.appendChild(iframe);
就是这样。
要记住一点:如果需要在 iframe 和其余内容脚本之间进行通信,则需要 chrome.runtime.sendMessage() 到后台页面,然后 chrome.tabs.sendMessage 从背景页面回到选项卡。他们不能直接交流。
编辑:我写了一篇博文,详细介绍了我在这个过程中学到的一切,包括一个完整的示例 chrome 扩展和许多指向不同信息的链接:
https://apitman.com/3/#chrome-extension-content-script-stylesheet-isolation
如果我的博客出现故障,这里是原始帖子的来源:
Blog post
Example source
【讨论】:
顺便说一句,如该博客文章中所述,您可能需要查看我的 chromeps 库来处理消息传递。这个blog post 解释了它【参考方案2】:要么使用all
.some-selector
all: initial;
.some-selector *
all: unset;
或使用 Shadow DOM
图书馆
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>';
您可以通过myWidget.inner
和外部通过myWidget.outer
访问小部件内容。
样式
/*
* 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;
【讨论】:
Shadow DOM 在事件处理方面非常棘手。我正在尝试使用 React + Shadow DOM 来隔离扩展,但仍然无法将事件处理程序绑定到内部 DOM。 我也做了同样的事情。最后我意识到 react 和 shadow dom 不能很好地协同工作。在封装方面,好的旧 iframe 仍然是最佳选择。 很高兴听到有人和我在一起。但似乎如果您使用的是 iframe,主机和 iframe 内容之间的消息传递可能会非常困难。你是怎么做到的?【参考方案3】:我最近创建了 Boundary,一个 CSS+JS 库来解决这样的问题。 Boundary 创建的元素与现有网页的 CSS 完全分离。
以创建对话框为例。安装 Boundary 后,您可以在内容脚本中执行此操作
var dialog = Boundary.createBox("yourDialogID", "yourDialogClassName");
Boundary.loadBoxCSS("#yourDialogID", "style-for-elems-in-dialog.css");
Boundary.appendToBox(
"#yourDialogID",
"<button id='submit_button'>submit</button>"
);
Boundary.find("#submit_button").click(function()
// some js after button is clicked.
);
#yourDialogID 中的元素不会受到现有网页的影响。 find() 函数返回一个常规的 jQuery DOM 元素,所以你可以用它做任何你想做的事情。
希望这会有所帮助。如果您有任何问题,请告诉我。
https://github.com/liviavinci/Boundary
【讨论】:
好!现在这是一个更好的答案。 (虽然要去掉sn-p标签,但没用) @Xan 这是我第一次在 *** 上发布答案,非常感谢您的指导! 这对用户事件响应良好吗?【参考方案4】:在提出问题时,您唯一的选择是使用 iframe 或 specificity 非常高的样式表,并明确设置所有可能影响样式的属性。最后一种方法很麻烦,因为总会有一些属性被你忽略。因此,隔离样式表的唯一可用方法是使用 iframe。
这个问题的解决方案 - 没有 iframe 的样式隔离 - 是 Shadow DOM (since Chrome 25)。您可以在HTML5 Rocks 找到教程。有关使用 Shadow DOM 隔离样式的真实 Chrome 扩展程序,请参阅Display #Anchors (source code here)。
【讨论】:
Display #Anchors
扩展非常方便(例如,用于链接到 Chrome 扩展文档的特定部分;))
也使用 Sass 之类的:#myid .all-my-extension-styles ...
可能会解决这个问题?
@rob-w 你的答案似乎有点复杂。你能给出简化代码来注入一个元素并在其他元素的顶部覆盖它吗?
我能够创建一个 shadowDOM 元素,但是一旦加载它就会被页面覆盖。例如,在 Medium 编辑器中,它会显示一秒钟的阴影元素并隐藏。我能够在开发工具中检查元素。【参考方案5】:
使用 iframe。这是一种解决方法,但效果很好。
Maxime 写了一封article on it。
【讨论】:
如何检测 Chrome 中是不是安装了 Google Cast 扩展程序?
】如何检测Chrome中是不是安装了GoogleCast扩展程序?【英文标题】:HowtodetectifGoogleCastextensionisinstalledinChrome?如何检测Chrome中是否安装了GoogleCast扩展程序?【发布时间】:2015-12-2709:12:12【问题描述】:我正在开发一个GoogleCast发件... 查看详情
在 Google Chrome 扩展程序中使用 SSH
...想通过ssh将此文件发送到我本地网络中的另一台计算机。如何在我的chrome扩展程序中设置和使用ssh连接?【问题讨论】:可能重复:***.com 查看详情
如何在 Chrome 扩展程序 browser_action 中登录 Google?
】如何在Chrome扩展程序browser_action中登录Google?【英文标题】:HowcanIsignintoGoogleinsideaChromeExtensionbrowser_action?【发布时间】:2020-04-1919:26:40【问题描述】:我试图让这一切尽可能简单,以便它可以成为处于相同情况的其他人的资源... 查看详情
如何在 chrome 扩展中加载 Google Analytics 和 Facebook SDK?
】如何在chrome扩展中加载GoogleAnalytics和FacebookSDK?【英文标题】:HowtoloadGoogleAnalyticsandFacebookSDKinchromeextension?【发布时间】:2013-12-1722:02:44【问题描述】:我正在使用Kango框架开发一个chrome扩展,我希望同时使用GoogleAnalytics和facebo... 查看详情
如何使用 Chrome 扩展程序自动保存 Google Chrome 开发者工具的网络面板日志?
】如何使用Chrome扩展程序自动保存GoogleChrome开发者工具的网络面板日志?【英文标题】:HowtoautomatesavingthelogofNetworkpanelofGoogleChromeDevelopertoolsusingChromeextension?【发布时间】:2016-08-1600:51:02【问题描述】:假设我打开一个网络应用... 查看详情
Google Chrome 扩展程序 - 单击工具栏图标时打开新选项卡
...选项卡(例如:f.html)?我看到了thisquestion,但它并没有真正 查看详情
从脚本安装 Google Chrome 扩展
...(crx文件),但我不想将它上传到Chrome网上应用店。现在如何以编程方式(使用JavaScript或chromeAPI)在Googlechrome中安装此crx文件?我到处搜索,唯一的解决方案 查看详情
是否可以通过扩展从另一个进程外部触发 Google Chrome 中的 Javascript?
】是否可以通过扩展从另一个进程外部触发GoogleChrome中的Javascript?【英文标题】:IsitpossibletoexternallytriggerJavascriptinGoogleChromefromanotherprocess,maybeviaanextension?【发布时间】:2010-11-0818:28:27【问题描述】:我希望我的机器上的本地进... 查看详情
检测 Google Chrome 扩展的 browser_action 表单中的按钮点击
】检测GoogleChrome扩展的browser_action表单中的按钮点击【英文标题】:Detectabuttonclickinthebrowser_actionformofaGoogleChromeExtension【发布时间】:2021-12-2720:10:58【问题描述】:如此简单的事情怎么会如此不可能?我想要做的就是单击我的扩... 查看详情
如何在chrome上可以登录google
1.Ghelper的下载.解压(http://ghelper.xyz/)2.在谷歌浏览器==>更多工具==>扩展程序==>加载已解压的扩展程序(添加刚才下载的Ghelper)3.Ghelper按照注册流程,注册账号,登录接下来就可以登录Google网站了 查看详情
扩展 Google chrome 以显示证书列表
...间】:2017-05-3108:32:30【问题描述】:任何人都可以帮助我如何放置,任何人都有解决方案来做到这一点。【问题讨论】:【参考方案1】:Chrome扩展中没有任何机制可以:枚举已安装的证书。查看给定连接的证书详细信息。最接... 查看详情
如何在浏览器中获取 Google Cloud Translation API 的身份验证令牌(chrome 扩展)
】如何在浏览器中获取GoogleCloudTranslationAPI的身份验证令牌(chrome扩展)【英文标题】:HowtogetanauthenticationtokenforGoogleCloudTranslationAPIwithinbrowser(chromeextension)【发布时间】:2019-01-2501:31:43【问题描述】:我正在尝试制作一个使用Googl... 查看详情
Chrome扩展程序中的无Chrome窗口?
...为TypeFu的Web应用程序。让我吃惊的是他们居然创造了一个真正的无铬窗。我正在考虑是否可以在Chrome扩展程序中执行此操作,因为在大多数情况下它们使用相同的API。但是,我找不到任何可以让我做出 查看详情
oauth Chrome 扩展 Google App Engine
】oauthChrome扩展GoogleAppEngine【英文标题】:oauthChromeExtensionGoogleAppEngine【发布时间】:2013-11-0210:32:19【问题描述】:有没有人幸运地让GoogleChrome扩展程序和GoogleApp引擎之间的OAuth运行良好(或者其他任何事情?)。我已经完成了所... 查看详情
如何在我的 Google Chrome 扩展程序中将信息从 Background.js 传递到 autofill.js?
】如何在我的GoogleChrome扩展程序中将信息从Background.js传递到autofill.js?【英文标题】:HowcanIpassinformationfromBackground.jstoautofill.jsinmyGoogleChromeextension?【发布时间】:2014-04-0701:28:51【问题描述】:我制作了一个GoogleChrome扩展程序,当... 查看详情
在 google-chrome 扩展中加载 iframe(错误:协议必须匹配)
】在google-chrome扩展中加载iframe(错误:协议必须匹配)【英文标题】:Loadingiframeingoogle-chromeextension(Error:Protocolsmustmatch)【发布时间】:2012-12-2622:30:08【问题描述】:manifest.json中的代码:"name":"Test","version":"1.0","manifest_version":2,"des... 查看详情
如何同步 chrome 扩展选项
】如何同步chrome扩展选项【英文标题】:Howtosyncchromeextensionoptions【发布时间】:2011-05-1123:06:46【问题描述】:我制作了一个带有选项页面的Chrome扩展程序。数据保存在本地存储中并且可以正常工作。Chrome不会将本地存储同步到... 查看详情
如何与电子中的chrome扩展背景页面通信?
】如何与电子中的chrome扩展背景页面通信?【英文标题】:Howtocommunicatewithchromeextensionbackgroundpageinelectron?【发布时间】:2022-01-2101:31:49【问题描述】:由于电子没有实现chrome.runtime.onMessageExternal。我们如何在main或renderer进程中与c... 查看详情