Добавление элемента стиля до завершения загрузки целевой страницы

Я создаю пользовательский скрипт и, чтобы избежать страшного эффекта «дрожания», поскольку пользовательский скрипт редактирует стили страницы после завершения рендеринга страницы, я пытаюсь сделать это, пока страница все еще загружается.

Выполнение этого путем вставки правил в уже существующий объект стиля работает должным образом....
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

person JBradwell    schedule 08.02.2012    source источник


Ответы (1)


Несколько вещей:

  1. Для изменения стиля не изобретайте велосипед. Используйте расширение Stylish. Это позволяет быстро и легко вносить изменения, а также делиться/повторно использовать стили. На userstyles.org уже разработано множество стилей.

  2. Если вы все равно хотите, чтобы это было в сценарии, избегайте всех этих таблиц стилей и addRule() ригамарол. Просто добавьте CSS, используя манифест скрипта. :

    1. Create a CSS file with your changes, EG:
      * {background-color:lime!important;}
      and place it in the same folder as your script's JS.
    2. Добавьте в файл манифеста строку, включающую файл CSS. Например:
      "css": [ "myCSS.css" ],
    3. См. этот ответ для получения дополнительной информации о расположении сценариев и файле манифеста.

  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. Правило устанавливается для универсального селектора (*). Это означает, что более конкретные правила могут иметь приоритет над ним. Таким образом, вам может потребоваться быть более конкретным, например: body {background-color:lime!important;}, чтобы изменения закрепились.
person Brock Adams    schedule 09.02.2012