提问人:jcubic 提问时间:11/6/2023 最后编辑:jcubic 更新时间:11/6/2023 访问量:74
为什么使用 CSS insertRule 时 DOM 不更新?
Why DOM is not updated when using CSS insertRule?
问:
我想向 DOM 添加一个 CSS 规则:
这是我的代码
function empty_rule(sheet, class_name) {
const index = sheet.cssRules.length;
sheet.insertRule(`.${class_name} { }`, index);
return sheet.cssRules[index];
}
function make_style() {
const $head = $('head');
const $style = $('<style type="text/css"/>').appendTo($head);
return $style.get(0).sheet;
}
function set_css(sheet, class_name, style) {
const selector = `.${class_name}`;
let rule = [...sheet.cssRules].find(rule => {
return rule.selectorText === selector;
});
if (!rule) {
rule = empty_rule(sheet, class_name);
}
Object.assign(rule.style, style);
}
const sheet = make_style();
const rule = empty_rule(sheet, 'cmd-terminal');
console.log(sheet);
console.log(rule);
/*
set_css(sheet, 'cmd-terminal', {
color: 'red'
});
*/
在 CodePen 上,我添加了这个 CSS 来查看 CSS:
style {
display: block;
white-space: pre;
font-family: monospace;
}
但是我没有看到添加任何CSS,我尝试在评论中添加给定的CSS。但我什至没有看到空的规则。我在问 chatGPT,但它对解决问题没有任何帮助。
这是 CodePen 链接
我使用现金库(轻量级 jQuery 替代方案)。
我试图添加到空规则中(这是 chatGPT 的建议),但它并没有解决问题。display: block;
我什至尝试了 MDN 中的内容:
$('body style').get(0).sheet.insertRule("#blanc { color: white }", 0);
但风格没有改变。
编辑:我添加了:
这个 HTML:
<p id="blanc">hello</p>
我在 Firefox、Google Chrome 和 Safari 中也有相同的行为。
当 JavaScript 运行时,标签会消失。那么问题来了,为什么DOM(devTools)中没有更新样式,为什么我添加的样式没有出现(添加时)?display: block
是否可以更新 DOM,以便您可以更轻松地调试 CSS?
答:
因此,cssRules 似乎在 DOM 中不可见。但是您可以创建调试代码来转储 CSS 并将其添加回 DOM:
function dump_css(sheet) {
return [...sheet.cssRules].map(rule => rule.cssText).join('\n')
}
$('head style:last-child').text(dump_css(sheet));
这会将动态 CSS 呈现到 DOM 中。此代码可以在调试时使用。
您似乎期望修改“virtual”将反映回 HTMLStyleElement 的“”。但显然,它不会:sheet.CSSRules
innerHTML
<style
id=s
contenteditable
style="
display: block;
white-space: pre;
border: inset;
">body {
background-color: darkslategray;
color: tan;
}
[onclick]:empty::after { content: attr(onclick); }
</style>
i:
<input id=i value="body { color: red; }">
<button onclick="
s.sheet.insertRule(i.value, s.sheet.rules.length);
"></button>
这表明,在不更改原始元素内容的情况下,将新规则添加到附加到样式元素的工作表中具有效力。
评论
在网页中,文档对象模型 (DOM) 不会立即更新,以反映通过使用 insertRule 方法添加新的 CSS 规则对样式表所做的更改。这通常会让开发人员感到困惑,他们认为使用 insertRule 添加新的 CSS 规则会立即更改页面的样式。
这是因为 CSS 对象模型 (CSSOM) 提供了 insertRule 方法,该方法的功能级别低于 DOM。它不会导致页面自动重排或重绘;相反,它允许您以编程方式将新的 CSS 规则添加到样式表中。换句话说,它可以防止浏览器立即重新计算样式并更新呈现的输出。
通常,您必须强制重排或重绘页面,以观察新插入的 CSS 规则的后果。可以更改 DOM 元素的类名,可以更新其内联样式,也可以强制更改布局。下面是如何将最近添加的 CSS 规则应用于特定 JavaScript 元素的示例:
// Create a new CSS rule
var stylesheet = document.styleSheets[0]; // Assuming the stylesheet you want to modify is the first one
var rule = "p { color: red; }";
stylesheet.insertRule(rule, 0); // Insert the rule at the beginning of the stylesheet
// Apply the new CSS rule to a specific element
var paragraph = document.querySelector("p"); // Select the desired paragraph element
paragraph.style.color = "red"; // Update its inline style to trigger the change
在此示例中,我们编辑特定 p 元素的内联样式以立即应用新样式,并包含新的 CSS 规则以将所有 p 元素的文本颜色更改为红色。
虽然 insertRule 支持动态样式表编辑,但它可能只支持有限数量的旧浏览器。因此,您在使用它时应谨慎行事,以防止意外行为。为了更新 DOM 和动态更改样式,类和 JavaScript 的使用频率更高。
评论