如何使用 XUL、SDK 或 WebExtensions 技术从 Firefox 附加组件中的 JavaScript 动态修改 CSS 规则集(例如,使用类选择器)?尝试支持 Firefox 29.0b1 到 49.0a1。
我想解决的问题(来自 Firefox 附加组件中的 XUL 文档,有时与网页不同):
file.xul:
(顶部有这一行)
<?xml-stylesheet href="chrome://{GUID}/skin/text.css" type="text/css"?>
text.css:
(文件中的相关类)
.myTextClass {
max-width: 800px;
}
code:
// Modify the class selector rule set to add another rule,
// i.e. font-family: DejaVu Sans Mono
// Later on, after user input, change or remove this font in this one class
这可能是 #20927075 的部分副本,没有令人满意的答案,但我对 SDK 或 WebExtensions 技术也很感兴趣,以确保我想添加到现有的基于 XUL 的附加组件的功能可以用更新的 API 实现。
我想实现一个基本的“字体选择器”UI 功能,并将新字体应用到类中。我有一个带有类选择器的简单 CSS 规则集,它用一个规则定义一个类(目前,但可能手动/静态添加了其他规则集),我想向其添加另一条规则,并添加附加组件界面更新。
我知道的选项,但似乎都太笨拙了。
1) document.getElementById,设置style
手动属性。我为演示区执行此操作,没问题。
2) 和上面类似,但是getElementByClassName。但是,这不是使用类!这是使用一个类来查找节点,我将每个元素的属性(样式或类)更改为该节点。这似乎相当缓慢。我可以创建一个包含每种可能字体的类的大型 CSS 文件,然后更改类属性,但这是愚蠢的。比仅仅改变样式属性更糟糕。
3) 有样式表服务,但我不知道它是否仍然存在或将被废弃或删除(它是基于 XPCOM 的吗?),它不是 Services.jsm 的一部分,它是一个非常生硬的工具当我只想修改一个类定义中的一个规则时,它只能加载或卸载整个样式表。
4) 有 jQuery,但是没有。就是不行。甚至不建议那样做。对于一个小的附加组件来说开销太大,并且不知道该技术是否适用于 XUL 接口(interface)代码。
5) 像 document.styleSheets 这样的东西看起来是正确的但没有得到我想要的东西(除非我弄错了?)。一切似乎都是只读的。更多内容如下。
6) 通过摆弄 document.getElementsByTagName('head') 手动破坏整个样式表,这再次破坏整个 css 表而不是一个类的一个规则。
如果真的没有别的办法,我可能不得不使用上面的方法2。但我希望有一个选项允许使用 JavaScript 从 XUL 中对 CSS 进行细粒度控制。
我正在尝试了解如何做到这一点:
for ( i = 0; i < document.styleSheets.length; i++ ) {
styleSheet = document.styleSheets[ i ];
console.log( 'style sheet: ' + i + ' ' + styleSheet.href );
if ( styleSheet.href === 'chrome://{GUID}/skin/text.css' ) {
for ( j = 0; j < styleSheet.cssRules.length; j++ ) {
styleRule = styleSheet.cssRules[ j ];
console.log( 'style sheet: ' + i + ' ' + 'styleRule: ' + styleRule.cssText );
}
}
}
在这次编辑过程中,我现在获得了显示定义类的规则的代码,而昨晚我遇到了一个无效的属性错误。我混淆了我的术语,认为规则是类里面的行元素。但无论如何,从那时起,我不确定如何继续。
以上代码(在 file.js
中,从 file.xul
<script>
标签中引用)输出类似于此的 console.log(在 Firefox 29.0b1 中):
"style sheet: 0 chrome://git-addonbar/skin/addonbar.css" file.js:189
09:49:47.101 "style sheet: 1 chrome://browser/content/browser.css" file.js:189
09:49:47.101 "style sheet: 2 chrome://browser/content/places/places.css" file.js:189
09:49:47.101 "style sheet: 3 chrome://browser/skin/devtools/common.css" file.js:189
09:49:47.101 "style sheet: 4 chrome://browser/skin/customizableui/panelUIOverlay.css" file.js:189
09:49:47.101 "style sheet: 5 chrome://browser/skin/browser.css" file.js:189
09:49:47.101 "style sheet: 6 chrome://browser/skin/browser-lightweightTheme.css" file.js:189
09:49:47.101 "style sheet: 7 chrome://global/skin/global.css" file.js:189
09:49:47.101 "style sheet: 8 chrome://{GUID}/skin/text.css" file.js:189
09:49:47.102 "style sheet: 8 styleRule: .myTextClass { max-width: 800px; }" file.js:194
09:49:47.102 "style sheet: 9 null" file.js:189
最佳答案
5) There's things like document.styleSheets which doesn't seem to get what I want (unless I am mistaken?). Everything seems read-only.
这是正确的选项。虽然 styleSheets
属性是只读的(这意味着您不能像这样分配:document.styleSheets = val
),但您获得的样式表对象允许修改。
因为您只关心一个(现代!)浏览器,这比 Changing a CSS rule-set from Javascript 更容易以跨浏览器的方式。一个简单的例子:
function changeCSS() {
let myClassRule = document.styleSheets[0].cssRules[0];
if (myClassRule.style.color == "red")
myClassRule.style.color = "blue";
else
myClassRule.style.color = "red";
}
.my-class {
color: red;
}
<p class="my-class">First paragraph</p>
<p class="my-class">Second paragraph</p>
<button onclick="changeCSS()">Change the stylesheet!</button>
您必须扩展它才能找到您关心的样式表和规则 - 上面链接的问题有 a minimal example of doing that .
关于javascript - 如何使用 XUL、SDK 或 WebExtensions 技术从 Firefox 附加组件中的 JavaScript 动态修改 CSS 规则集(例如,使用类选择器)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37496652/