有什么方法可以 select CSS class 和 DOM 中不存在的 JS?
Are there any ways to select a CSS class with JS that doesn't exist in DOM?
是否可以 select CSS class
与 registered 仅在其文件中,不存在于 [=] 中的 JS 37=]?
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>
像这个例子, select 和 .class1
没有问题,因为它存在于 DOM 元素中。
但我想访问 DOM 中不存在的 .class2
。
有没有办法做到这一点?
访问此类元素的唯一可能方法是事先引用它或它的父元素之一。通常的方法是使用从 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
如果看不到元素的创建位置,这些方法将不起作用。在这种情况下,您唯一的其他选择是在创建元素的脚本运行 之前 对可以创建元素的各种方法进行 monkeypatch,(例如 createElement
、innerHTML
setter、outerHTML
setter 等)但这几乎总是一个非常糟糕的主意,除非没有其他选择(比如如果您正在编写用户脚本)。
XY 问题在这里...您不是想要获取元素,而是样式表中设置的值。
即使这可能是可能的(它是,但非常复杂),但该方法存在一个很大的缺陷:因为存在 CSS 规则并不意味着它会得到应用.
例如,在您的情况下,.class2
规则确实存在并且处于活动状态,但是,由于没有元素匹配此规则,它不会有任何效果。
同样,即使一个元素确实匹配这条规则,它也很可能被其他规则覆盖:
console.log(
getComputedStyle(
document.querySelector('.class2')
).getPropertyValue('top')
); // "10px"
#foo { top: 10px };
.class2 { top: 50px; }
<div class="class2" id="foo"></div>
所以,是的,您可以获得 CSS 规则的设定值:
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; }
但是再一次,这真的没有用,大多数时候,你只需要在你的元素附加到 DOM 后调用 getComputedStyle
(调用它是没有用的之前,因为没有 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;
}
是否可以 select CSS class
与 registered 仅在其文件中,不存在于 [=] 中的 JS 37=]?
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>
像这个例子, select 和 .class1
没有问题,因为它存在于 DOM 元素中。
但我想访问 DOM 中不存在的 .class2
。
有没有办法做到这一点?
访问此类元素的唯一可能方法是事先引用它或它的父元素之一。通常的方法是使用从 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
如果看不到元素的创建位置,这些方法将不起作用。在这种情况下,您唯一的其他选择是在创建元素的脚本运行 之前 对可以创建元素的各种方法进行 monkeypatch,(例如 createElement
、innerHTML
setter、outerHTML
setter 等)但这几乎总是一个非常糟糕的主意,除非没有其他选择(比如如果您正在编写用户脚本)。
XY 问题在这里...您不是想要获取元素,而是样式表中设置的值。
即使这可能是可能的(它是,但非常复杂),但该方法存在一个很大的缺陷:因为存在 CSS 规则并不意味着它会得到应用.
例如,在您的情况下,.class2
规则确实存在并且处于活动状态,但是,由于没有元素匹配此规则,它不会有任何效果。
同样,即使一个元素确实匹配这条规则,它也很可能被其他规则覆盖:
console.log(
getComputedStyle(
document.querySelector('.class2')
).getPropertyValue('top')
); // "10px"
#foo { top: 10px };
.class2 { top: 50px; }
<div class="class2" id="foo"></div>
所以,是的,您可以获得 CSS 规则的设定值:
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; }
但是再一次,这真的没有用,大多数时候,你只需要在你的元素附加到 DOM 后调用 getComputedStyle
(调用它是没有用的之前,因为没有 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;
}