Установка правил псевдокласса CSS из JavaScript

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

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

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

Ответ 1

Вы не можете создать псевдокласс для отдельного элемента, так же, как вы не можете иметь псевдокласс в встроенном атрибуте 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';

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

Ответ 2

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

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

Ответ 3

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

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);
    }
  }
};

Ответ 4

Мой трюк использует селектор атрибутов. Атрибуты легче настроить с помощью 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

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

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

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

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

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

Ответ 6

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

Ответ 7

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

Настройте файлы 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;
     }
   }
}

Ответ 8

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

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

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";  

Ответ 9

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

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

Ответ 10

В jquery вы можете легко установить псевдо-классы hover.

$("p").hover(function(){
$(this).css("background-color", "yellow");
}, function(){
$(this).css("background-color", "pink");
});

Ответ 11

Если вы используете РЕАКТ, есть что-то, называемое radium. Это так полезно здесь:

  • Добавить обработчики для реквизита, если указаны интерактивные стили, например. onMouseEnter for: наведите указатель мыши на перенос существующих обработчиков

  • Если какой-либо из обработчиков запускается, например. путем зависания, Radium вызывает setState для обновления поля, специфичного для Radium, для компонентов объект состояния

  • При повторной обработке разрешите любые применяемые интерактивные стили, например.: наведите курсор, просмотрев ключ элемента или ref в специфичном для Radium состояние

Ответ 12

здесь есть решение, включающее две функции: 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>