如何解决如何将 css 应用于没有属于自己的标签的元素?
假设有一个 html 看起来像
<div id="a">
123
<span id="b">456</span>
789
</div>
我只想将 css 应用于 123,而不是 456
如果我将 css 应用到 top div (id=a),它会影响 123 和 456,因为 <span id="b">456</span>
也属于 top div (id=a)
在 123 左右添加跨度不是一个选项,因为 html 本身不在我的控制之下。
我所做的就是尝试像这样获得 123。
const node123 = getElementById('a').childNodes[0]
node123.style.backgroundColor = "red"
但代码失败并显示“TypeError: Cannot set property 'backgroundColor' of undefined.
我发现文本元素节点 (node123) 没有样式。
const node456 = getElementById('a').childNodes[1]
node456.style.backgroundColor = "red"
我认为它有效,因为它不是文本元素而是带有标签的节点(在这种情况下为跨度)
如何将css应用到node123而不在node123周围添加span标签,这是没有标签的文本元素?
谢谢
解决方法
在 123 左右添加跨度不是一个选项,因为 html 本身不在我的控制之下。
也许不是直接的 - 但你的问题的其余部分清楚地表明你可以运行你自己的 Javascript 并使用它来操作样式(包括内联样式)。那么为什么不使用 JS 来操作 DOM 以将其包装在一个 span
中,然后您可以对其进行样式设置?
const container = document.getElementById('a');
const node123 = container.childNodes[0];
const wrapped123 = document.createElement('span');
wrapped123.appendChild(node123);
wrapped123.style.backgroundColor = 'red';
container.prepend(wrapped123);
<div id="a">
123
<span id="b">456</span>
</div>
TextNodes are not meant to be styled。如果您只想更改一些与文本相关的属性,您确实可以根据一些 :not()
规则继续并修改样式。所有与框相关的属性(以及其中的 backgroundColor)仍将应用于整个 <div>
。
仍然有一种方法,该代码段演示了它:
const btn = document.querySelector('button');
const div = document.getElementById('a');
btn.addEventListener('click',() => {
const isPristine = div.classList.contains('pristine');
isPristine ? wrapTextNodes(div) : unwrapTextNodes(div);
div.classList.toggle('pristine');
});
function wrapTextNodes(div) {
const childNodes = Array.from(div.childNodes);
childNodes.forEach(node => {
if (node.nodeType !== Node.TEXT_NODE) return;
if (!/\S/.test(node.data)) return;
const wrapperSpan = document.createElement('span');
wrapperSpan.classList.add('wrapper');
wrapperSpan.appendChild(
div.replaceChild(wrapperSpan,node));
});
}
function unwrapTextNodes(div) {
div.querySelectorAll('wrapper').forEach(wrapper => {
div.replaceChild(wrapper.childNodes[0],wrapper);
});
}
#a {
color: green;
font-size: 30px;
line-height: 1.5em;
}
#a.pristine {
background-color: pink;
}
#b,#c,#d {
color: navy;
background-color: white;
}
#a .wrapper {
background-color: pink;
}
<div id="a" class="pristine">
123
<span id="b">456</span>
789
<span id="c">111</span>
<span id="d">222</span>
</div>
<br />
<button type="button">Change it all!</button>
这个想法是,您可以即时包装您的 textNodes(这可能是渲染过程的最后 步骤)并在必要时解开它们,只需进行一点 DOM 操作.但是,在执行此操作时必须对边缘情况保持谨慎; RTL 文本存在一些问题,甚至无法让我开始了解双向。
除此之外还有另一种选择:有许多 z-index 足够高的“样式”元素,位于要设置样式的文本节点上。这是可能的(例如,一些读者使用注释来做到这一点),但这往往会出现故障(必须为每个影响布局的事件正确地重新应用所有叠加层)。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。