【问题标题】:Adding a style element before the target page has finished loading在目标页面完成加载之前添加样式元素
【发布时间】:2012-02-08 15:24:22
【问题描述】:

我正在构建一个用户脚本,并且为了避免在页面完成渲染后用户脚本编辑页面样式时出现可怕的“抖动”效果,我正在尝试在页面仍在加载时执行此操作。

通过将规则插入到预先存在的样式对象中来执行此操作,可以按预期工作....
http://pastebin.com/NNjLjKA5 ...等到样式对象存在,然后向其添加新样式。

但是,当尝试创建新样式对象以将规则插入其中时,我遇到了奇怪的行为...

// ==UserScript==
// @name           script
// @include        *
// @run-at document-start
// ==/UserScript==

// Add style rules while page is loading (to prevent jumping)
function addStyleRules(){

    // Check if stylesheets exist yet, if not try again in a bit
    if( !document.styleSheets[0] ) return setTimeout( addStyleRules,1 );

    // Get/create stylesheet element (if not already created)
    if( !document.querySelector( 'style[title=new_stylesheet]' ) ){
        var css = document.createElement( 'style' );
        css.type = "text/css";
        document.head.appendChild( css );
        css.title = 'new_stylesheet';
    }

    // Get stylesheet object
    var ss;
    for(i in document.styleSheets )
        if( document.styleSheets[i].title == 'new_stylesheet' )
            ss = document.styleSheets[i];

    // Add style rules
    if(ss.addRule)
        ss.addRule( '*','background-color:black',0);
    else
        ss.insertRule('*{background-color:black}',0);

    //debug
    console.log( 'page loading', ss, new Date().getTime() );
}
addStyleRules();

// Page has finished loading
document.addEventListener('DOMContentLoaded',function(e){

    // Get stylesheet object
    var ss;
    for(i in document.styleSheets )
        if( document.styleSheets[i].title == 'new_stylesheet' )
            ss = document.styleSheets[i];

    //debug
    console.log('page loaded', ss, new Date().getTime() );
});


此脚本应该创建一个新的样式元素,在“document.styleSheets”中找到新的样式对象,然后应用新规则。

正如第一个日志事件所观察到的那样,这似乎做得很好。然而,一旦页面完成加载,新的样式对象就不再存在(即使样式元素存在于 DOM 中)。

所以是的,我的问题是......
新创建的样式表对象在创建、成功应用新规则和触发“DOMContentLoaded”事件之间发生了什么?

  • 浏览器是 Chrome 16.0.912.77

【问题讨论】:

    标签: javascript css userscripts


    【解决方案1】:

    几件事:

    1. 对于样式覆盖,不要重新发明轮子。 使用the Stylish extension它允许快速、轻松地更改和共享/重用样式。 userstyles.org 已经开发了无数种样式。

    2. 无论如何,如果您想在脚本中使用它,请避免使用所有样式表和addRule() rigamarole。只需使用您的脚本清单添加 CSS。

      1. 使用您的更改创建一个 CSS 文件,例如:
        * {background-color:lime!important;}
        并将其放在与脚本的 JS 相同的文件夹中。
      2. 在包含 CSS 文件的清单文件中添加一行。例如:
        "css": [ "myCSS.css" ],
      3. 有关脚本位置和清单文件的更多信息,请参阅 this answer

    3. 您当前的脚本有效,但显然没有给出您想要的结果,因为脚本设置的规则 (background-color:black) 已被后来的 CSS 否决。

      1. 使用!important 关键字阻止大多数(但不是全部)后来的 CSS 规则优先。例如:

        if (ss.addRule)
            ss.addRule ('*', 'background-color:black!important;', 0);
        else
            ss.insertRule ('*{background-color:black!important;}', 0);
        

        根据您的情况,这可能就是您所需要的,但请参阅第 1 点和第 2 点。;)

      2. 正在针对通用选择器 (*) 设置规则。这意味着more-specific rules may override it。因此,您可能需要更具体一些,例如:body {background-color:lime!important;} 才能使更改生效。

    【讨论】:

      猜你喜欢
      • 2010-12-23
      • 2021-07-05
      • 2020-07-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多