4 javascript css dom xul firefox-addon
如何使用 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 接口代码中工作。
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)像 document.styleSheets 这样的东西似乎没有得到我想要的(除非我弄错了?)。一切似乎都是只读的。
这是正确的选项。虽然该styleSheets属性是只读的(意味着您不能像这样分配:)document.styleSheets = val,但您获得的样式表对象确实允许修改。
由于您只关心一种(现代!)浏览器,因此这比以跨浏览器方式从 Javascript 更改 CSS 规则集更容易。一个简单的例子:
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>您必须扩展它才能找到样式表和您关心的规则 - 上面链接的问题有一个最小的示例。