Есть ли способы выбрать класс CSS с JS, который не существует в DOM? - PullRequest
0 голосов
/ 12 мая 2019

Можно ли выбрать CSS class с JS, который зарегистрирован только в своем файле, но не существует в DOM?

var elem = document.getElementsByClassName('class2')[0],
    getStyle = window.getComputedStyle(elem),
    value = getStyle.getPropertyValue('top');
console.log(value);
// Can't get the value of class2 because it doesn't exist in DOM. 
.class1 {
  top: 10px;
}
.class2 {
  top: 20px;
}
<div class="class1">
  top
</div>

Как и в этом примере, нет проблем с выбором .class1, поскольку он существует в DOM внутри элемента.

НоЯ хочу получить доступ к .class2, который не существует внутри DOM.

Есть ли способы сделать это?

Ответы [ 2 ]

1 голос
/ 12 мая 2019

XY Проблема здесь ... Вы не хотите получить элемент, но значение, установленное в таблицах стилей.

Даже если это возможно (да, но очень запутанно), у этого подхода есть большой недостаток: Поскольку правила CSS существуют, это не значит, что они будут применены .

Например, в вашем случае правило .class2 действительно существует и активно, однако, поскольку ни один элемент не соответствует этому правилу, оно не будет иметь никакого эффекта.
Точно так же, даже если элемент соответствует этому правилу, он вполне может быть переопределен другим правилом:

console.log(
  getComputedStyle(
    document.querySelector('.class2')
  ).getPropertyValue('top')
); // "10px"
#foo { top: 10px };
.class2 { top: 50px; }
<div class="class2" id="foo"></div>

Итак, да, вы можете получить установленное значение CSSRule:

const matching_rules = [...document.styleSheets].reduce((matched, sheet) => {
  [...sheet.cssRules].forEach( r => {
      if(r.selectorText && r.selectorText.includes('.class2'))
        matched.push(r.style.top);
  });
  return matched;
}, []);
console.log(matching_rules);
.class2 { top: 50px; }

Но, опять же, это действительно бесполезно, и в большинстве случаев вам просто нужно вызвать getComputedStyle, как только ваш элемент был присоединен к DOM (его бесполезно вызывать раньше, так как правило CSS не применяется) на элементах, которые не отображаются.

const elem = document.createElement('div');
elem.classList.add('class2');
console.log('matches:', elem.matches('.class2')); // true
const comp = getComputedStyle(elem);
console.log('computed top:', JSON.stringify(comp.getPropertyValue('top'))); // "" (the default)
.class2 {
  top: 50px;
}
1 голос
/ 12 мая 2019

Единственным возможным способом доступа к такому элементу является предварительная ссылка на него или на один из его родительских элементов. Обычный способ - использовать ссылку на элемент, созданную из document.createElement, или любым другим способом, которым был создан элемент:

const element = document.createElement('div');
element.className = 'class2';

// element is not attached to the DOM, but you can still reference it here

// you can also retrieve elements created by assigning to the innerHTML of another element:
element.innerHTML = '<div class="class2"></div>';
const element2 = element.children[0];

// element2 is not attached to the DOM, but you can still reference it here

Если вы не видите, где создан элемент, эти методы не будут работать. В этом случае единственная другая опция - установить различные методы, которые могут создавать элементы до сценария, который создает элементы, (например, createElement, innerHTML setter, outerHTML setter, и т. д.), но это почти всегда очень плохая идея, если нет другой возможности (например, если вы пишете usercript).

...