@Alide

Как изменить стили через javascript?

Вот вообщем есть такой скрипт, который меняет высоту всех элементов под высоту первого элемента
<script>
var els = document.querySelectorAll("a[href='/products/962112']");

for (var i = 0, l = els.length; i < l; i++) {
var el = els[i];
el.innerHTML = el.style.height;
}
document.querySelector('.product').style.height = el.style.height; 
</script>

Но не работает , если делаю классы, работает , когда есть ID , но id сервис возможности не дает добавить к элементу
То есть работает , когда вместо document.querySelector('.product').style.height = el.style.height; написано document.getElementsById('product').style.height = el.style.height; Т.е работает только с ID , как сделать, чтобы можно работало с классами? document.getElementsByClassName тоже не получается
  • Вопрос задан
  • 478 просмотров
Пригласить эксперта
Ответы на вопрос 1
bingo347
@bingo347 Куратор тега JavaScript
Crazy on performance...
var el = document.querySelector("a[href='/products/962112']"); // в селекторе хардкод... не будет ссылки с таким href - все сломается

// тут был цикл, но я его убрал, ибо один элемент берем

var products = document.getElementsByClassName('product'); // тут коллекция, ее надо перебирать циклом
for(var i = 0; i < products.length; i++) {
  products[i].style.height = el.style.height;
}


UPD: по просьбе origami1024 добавляю вариант с CSSOM
Во-первых, нам понадобится новый элемент style, чей CSSOM мы будем править, его стоит разместить ниже других стилевых подключений (не важно через style или link), я же просто добавлю в конец head
Сам CSSOM элемента style доступен через его свойство sheet - извлеку его сразу в переменную:
const {sheet} = document.head.appendChild(document.createElement('style'));

Во-вторых, в CSSOM правила пронумерованы с 0. Притом можно заменять существующие правила по их индексу, а можно вставлять новые в конец (индекс при этом так же нужно указывать, а если указать неверно - выкинет эксэпшн). Нам же удобнее обращаться к правилам по селектору, поэтому я сделаю объект для сопоставления селектора с индексом правила и счетчик индексов:
const rulesIndexesBySelector = {};
let nextIndex = 0;

Ну и наконец реализуем вспомогательную функцию для обновления CSSOM правила по его селектору:
function updateRule(selector, declarations) {
  const rule = `${selector}{${declarations}}`; // полное правило - селектор + декларации в {}
  if(selector in rulesIndexesBySelector) {
    // индекс селектора уже известен, обновим правило
    const index = rulesIndexesBySelector[selector];
    sheet.deleteRule(index); // сначала удалим старое правило освободив индекс и отменив его свойства
    sheet.insertRule(rule, index); // и вставим на его место новое
  } else {
    // новый селектор
    const index = nextIndex++; // важен именно постинкримент, чтоб самый первый получил 0, второй 1 и т.д.
    rulesIndexesBySelector[selector] = index; // запомним на будущее
    sheet.insertRule(rule, index); // и вставим правило в конец
  }
}

Пример примитивный, но каждый думаю спокойно расширит его под себя.
У меня например declarations собираются из vue объекта, который можно мутировать (реактивные стили оО) + добавляются вендорные префиксы, если браузер не знает каких-то свойств (не автопрефиксер конечно, но зато работает по месту)

Использовать это все теперь можно крайне просто:
updateRule('.product', 'height: 40px; width: 50px');
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы