javascript - 如何使用 XUL、SDK 或 WebExtensions 技术从 Firefox 附加组件中的 JavaScript 动态修改 CSS 规则集(例如,使用类选择器)?

标签 javascript css dom firefox-addon xul

如何使用 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/

相关文章:

javascript - 使用变换和元素定位/大小

windows - 创建 .exe 文件以打开 .html 文档

javascript - 无法将 json 数据传递给 Ajax 函数

javascript - 使用预期条件时未定义属性 'bind'

javascript - 如何使用 Facebook api 在 Facebook 上分享文章并在帖子中显示文章缩略图?

css - 如何使用 Css3 旋转单个字符?

javascript - JavaScript 对象内的 jQuery 绑定(bind)

css - IFrame 在 IE 中重叠 Div(在 Chrome 中工作正常)

javascript - 尝试使用 Javascript 删除元素

javascript - 更改特定的内容,例如使用 DOM