提问人:Kritidipto Ghosh 提问时间:10/30/2023 最后编辑:KaiidoKritidipto Ghosh 更新时间:10/30/2023 访问量:77
为什么在重置 textContent 时会删除使用 insertRule 插入到空样式标记中的规则?
Why rules inserted in an empty style tag using insertRule get removed on resetting textContent?
问:
var styletag = document.createElement("style");
document.head.appendChild(styletag);
styletag.appendChild(document.createTextNode('')); // This is needed to replicate issue
styletag.sheet.insertRule("#inner { background-color: red;} ");
setTimeout(()=>styletag.textContent='',1000)
<span id="inner">content</span>
这段特定的代码会向元素添加适当的样式。直到代码运行并重置为空字符串。
然后样式表的规则 () 变为空,并且 被删除。
出于某种原因,需要第三行来复制此问题。#inner
setTimeout
textContent
styletag.sheet.cssRules
background-color
var styletag = document.createElement("style");
document.head.appendChild(styletag);
// styletag.appendChild(document.createTextNode('')); // This is needed to replicate issue
styletag.sheet.insertRule("#inner { background-color: red;} ");
setTimeout(()=>styletag.textContent='',1000)
<span id="inner">content</span>
如果我使用类似的东西,我本可以理解的
styletag.textContent = "#inner { background-color: red;} "
而不是
styletag.sheet.insertRule("#inner { background-color: red;} ");
在这里,重置为空将删除规则,这是有道理的。
也许设置使浏览器重新评估?但是,如果是这样,为什么只有当我在标签上附加一个空文本节点时,问题才可复制?textContent
textContent
CSSRules
<style>
答:
这很复杂,老实说也很令人惊讶,但问题的要点是,
在 3 种情况下,元素将根据其内容更新其规则:<style>
该元素从 HTML 解析器或 XML 解析器的打开元素堆栈中弹出。
该元素不在 HTML 解析器或 XML 解析器的打开元素堆栈中,并且它将连接或断开连接。
元素的子项更改了运行步骤。
在我们的例子中,第一个并不重要,因为我们是动态创建元素,而不是从解析器创建元素。
第二个也只是有限的重要性,当我们在 DOM 中附加元素时就会发生,但我们并不真正关心它以前是什么。唯一的问题是,当在 DOM 中,我们有一个从当前(空)内容中计算出来的第一个。sheet
然后我们让元素的子项改变一个。当插入节点(步骤 9)或删除节点(步骤 21)时,将调用此算法。因此,当您附加空时,将运行此步骤,并且将再次更新其规则,没有内容,再次...该更新也并不重要。但重要的是,现在,我们的确实有一个子节点。
事实上,当使用空字符串运行 textContent
setter 步骤时,目标元素的先前子元素将被删除,不会添加新节点,但仍会运行删除步骤。
但是,当目标元素中没有上一个子项时,不会删除任何节点,也不会添加任何新节点。插入步骤和删除步骤都不会运行,我们永远不会达到子级更改的步骤。TextNode
<style>
<style>
因此,这一切都归结为当有没有以前的内容时如何以不同的方式运行。textContent = ""
评论