Установка правил псевдокласса CSS из JavaScript - PullRequest
113 голосов
/ 22 ноября 2008

Я ищу способ изменить правила CSS для селекторов псевдоклассов (например,: link,: hover и т. Д.) Из JavaScript.

Итак, аналог кода CSS: a:hover { color: red } в JS.

Я не мог найти ответ где-либо еще; если кто-то знает, что это не поддерживается браузерами, это также будет полезным результатом.

Ответы [ 12 ]

176 голосов
/ 22 ноября 2008

Вы не можете стилизовать псевдокласс на отдельном элементе, так же, как вы не можете иметь псевдокласс в атрибуте inline style = "..." (так как нет селектора) .

Вы можете сделать это, изменив таблицу стилей, например, добавив правило:

#elid:hover { background: red; }

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

Теоретически документ, который вам нужен, это http://www.w3.org/TR/DOM-Level-2-Style/Overview.html, что означает, что вы можете (с учетом уже существующей встроенной или связанной таблицы стилей) использовать следующий синтаксис:

document.styleSheets[0].insertRule('#elid:hover { background-color: red; }', 0);
document.styleSheets[0].cssRules[0].style.backgroundColor= 'red';

IE, конечно, требует свой собственный синтаксис:

document.styleSheets[0].addRule('#elid:hover', 'background-color: red', 0);
document.styleSheets[0].rules[0].style.backgroundColor= 'red';

Старые и второстепенные браузеры, скорее всего, не поддерживают ни один из синтаксисов. Динамическое переключение таблиц стилей выполняется редко, потому что это довольно раздражает, когда нужно правильно, редко нужно и исторически хлопотно.

29 голосов
/ 22 февраля 2011

Я собрал небольшую библиотеку для этого , так как я думаю, что есть действительные варианты использования для управления таблицами стилей в JS. Причины:

  • Установка стилей, которые должны быть рассчитаны или получены - например, установка предпочтительного размера шрифта для пользователя из файла cookie.
  • Установка поведенческих (не эстетических) стилей, особенно для разработчиков виджетов / плагинов пользовательского интерфейса. Для вкладок, каруселей и т. Д. Часто требуется просто базовый CSS для работы - не нужно требовать таблицы стилей для основной функции.
  • Лучше, чем встроенные стили, поскольку правила CSS применяются ко всем текущим и будущим элементам и не загромождают HTML при просмотре в Firebug / Developer Tools.
16 голосов
/ 19 июня 2009

Функция для работы с кросс-браузерными функциями:

addCssRule = function(/* string */ selector, /* string */ rule) {
  if (document.styleSheets) {
    if (!document.styleSheets.length) {
      var head = document.getElementsByTagName('head')[0];
      head.appendChild(bc.createEl('style'));
    }

    var i = document.styleSheets.length-1;
    var ss = document.styleSheets[i];

    var l=0;
    if (ss.cssRules) {
      l = ss.cssRules.length;
    } else if (ss.rules) {
      // IE
      l = ss.rules.length;
    }

    if (ss.insertRule) {
      ss.insertRule(selector + ' {' + rule + '}', l);
    } else if (ss.addRule) {
      // IE
      ss.addRule(selector, rule, l);
    }
  }
};
6 голосов
/ 28 мая 2018

Просто поместите CSS в строку шаблона.

const cssTemplateString = `.foo:[psuedoSelector]{prop: value}`;

Затем создайте элемент стиля, поместите строку в тег стиля и прикрепите его к документу.

const styleTag = document.createElement("style");
styleTag.innerHTML = cssTemplateString;
document.head.insertAdjacentElement('beforeend', styleTag);

Специфика позаботится об остальном. Затем вы можете удалять и добавлять теги стиля динамически. Это простая альтернатива библиотекам и работа с массивом таблиц стилей в DOM. Удачного кодирования!

6 голосов
/ 01 января 2013

Мой трюк использует селектор атрибутов. Атрибуты легче настроить с помощью JavaScript.

CSS

.class{ /*normal css... */}
.class[special]:after{ content: 'what you want'}

Javascript

  function setSpecial(id){ document.getElementById(id).setAttribute('special', '1'); }

HTML

<element id='x' onclick="setSpecial(this.id)"> ...  
5 голосов
/ 03 июня 2011

Есть еще одна альтернатива. Вместо того, чтобы манипулировать псевдоклассами напрямую, создайте реальные классы, которые моделируют те же самые вещи, такие как класс «зависания» или «посещаемый» класс. Стиль классов с обычным "." синтаксис, а затем вы можете использовать JavaScript для добавления или удаления классов из элемента при возникновении соответствующего события.

3 голосов
/ 12 марта 2010

Вместо прямой установки правил псевдокласса с помощью javascript, вы можете по-разному устанавливать правила в разных файлах CSS, а затем использовать Javascript для отключения одной таблицы стилей и включения другой. Метод описан в Список отдельно (см. Более подробно).

Установить CSS-файлы как,

<link rel="stylesheet" href="always_on.css">
<link rel="stylesheet" title="usual" href="preferred.css"> <!-- on by default -->
<link rel="alternate stylesheet" title="strange" href="alternate.css"> <!-- off by default -->

А затем переключаться между ними, используя JavaScript:

function setActiveStyleSheet(title) {
   var i, a, main;
   for(i=0; (a = document.getElementsByTagName("link")<i>); i++) {
     if(a.getAttribute("rel").indexOf("style") != -1
        && a.getAttribute("title")) {
       a.disabled = true;
       if(a.getAttribute("title") == title) a.disabled = false;
     }
   }
}
2 голосов
/ 27 ноября 2008

Как уже говорилось, браузеры не поддерживают это.

Если вы не разрабатываете стили динамически (т. Е. Извлекаете их из базы данных или чего-то еще), вы можете обойти это, добавив класс в тело страницы.

CSS будет выглядеть примерно так:

a:hover { background: red; }
.theme1 a:hover { background: blue; }

И javascript, чтобы изменить это было бы что-то вроде:

// Look up some good add/remove className code if you want to do this
// This is really simplified

document.body.className += " theme1";  
1 голос
/ 10 августа 2010

Включение и выключение таблиц стилей - это способ сделать это. Вот библиотека для динамического создания таблиц стилей, так что вы можете устанавливать стили на лету:

http://www.4pmp.com/2009/11/dynamic-css-pseudo-class-styles-with-jquery/

0 голосов
/ 22 марта 2017

вот решение, включающее две функции: addCSSclass добавляет новый класс css в документ, а toggleClass включает его

В примере показано добавление пользовательской полосы прокрутки к div

// If newState is provided add/remove theClass accordingly, otherwise toggle theClass
function toggleClass(elem, theClass, newState) {
  var matchRegExp = new RegExp('(?:^|\\s)' + theClass + '(?!\\S)', 'g');
  var add = (arguments.length > 2 ? newState : (elem.className.match(matchRegExp) === null));

  elem.className = elem.className.replace(matchRegExp, ''); // clear all
  if (add) elem.className += ' ' + theClass;
}

function addCSSclass(rules) {
  var style = document.createElement("style");
  style.appendChild(document.createTextNode("")); // WebKit hack :(
  document.head.appendChild(style);
  var sheet = style.sheet;

  rules.forEach((rule, index) => {
    try {
      if ("insertRule" in sheet) {
        sheet.insertRule(rule.selector + "{" + rule.rule + "}", index);
      } else if ("addRule" in sheet) {
        sheet.addRule(rule.selector, rule.rule, index);
      }
    } catch (e) {
      // firefox can break here          
    }
    
  })
}

let div = document.getElementById('mydiv');
addCSSclass([{
    selector: '.narrowScrollbar::-webkit-scrollbar',
    rule: 'width: 5px'
  },
  {
    selector: '.narrowScrollbar::-webkit-scrollbar-thumb',
    rule: 'background-color:#808080;border-radius:100px'
  }
]);
toggleClass(div, 'narrowScrollbar', true);
<div id="mydiv" style="height:300px;width:300px;border:solid;overflow-y:scroll">
  Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed a eros metus. Nunc dui felis, accumsan nec aliquam quis, fringilla quis tellus. Nulla cursus mauris nibh, at faucibus justo tincidunt eget. Sed sodales eget erat consectetur consectetur. Vivamus
  a diam volutpat, ullamcorper justo eu, dignissim ante. Aenean turpis tortor, fringilla quis efficitur eleifend, iaculis id quam. Quisque non turpis in lacus finibus auctor. Morbi ullamcorper felis ut nulla venenatis fringilla. Praesent imperdiet velit
  nec sodales sodales. Etiam eget dui sollicitudin, tempus tortor non, porta nibh. Quisque eu efficitur velit. Nulla facilisi. Sed varius a erat ac volutpat. Sed accumsan maximus feugiat. Mauris id malesuada dui. Lorem ipsum dolor sit amet, consectetur
  adipiscing elit. Sed a eros metus. Nunc dui felis, accumsan nec aliquam quis, fringilla quis tellus. Nulla cursus mauris nibh, at faucibus justo tincidunt eget. Sed sodales eget erat consectetur consectetur. Vivamus a diam volutpat, ullamcorper justo
  eu, dignissim ante. Aenean turpis tortor, fringilla quis efficitur eleifend, iaculis id quam. Quisque non turpis in lacus finibus auctor. Morbi ullamcorper felis ut nulla venenatis fringilla. Praesent imperdiet velit nec sodales sodales. Etiam eget
  dui sollicitudin, tempus tortor non, porta nibh. Quisque eu efficitur velit. Nulla facilisi. Sed varius a erat ac volutpat. Sed accumsan maximus feugiat. Mauris id malesuada dui.
</div>
...