我需要使用JavaScript重新格式化输入HTML,以便生成的输出HTML始终是一系列<p>
个节点,其中只包含 一个或多个<span>
节点,每个节点{ {1}}节点应该只包含一个 <span>
节点。
为了提供示例,我想转换如下所示的HTML:
#text
对于看起来像这样的HTML:
<p style="color:red">This is line #1</p>
<p style="color:blue"><span style="color:yellow"><span style="color:red">This is</span> line #2</span></p>
<p style="color:blue"><span style="color:yellow"><span style="color:green">This is line #3</span></span>
<p style="color:blue"><span style="color:yellow">This is</span><span style="color:red">line #4</span></span></p>
附加的,有点切线的信息:
<p style="color:red"><span style="color:red">This is line #1</span></p>
<p style="color:red"><span style="color:red">This is</span><span style="color:yellow"> line #2</span></p>
<p style="color:green"><span style="color:red">This is line #3</span>
<p style="color:yellow"><span style="color:yellow">This is</span><span style="color:red">line #4</span></span></p>
有行高问题,嵌套跨度会导致TinyMCE中的编辑为非,直观)wkhtmltopdf
中可用,但不在此文档中。我自己能够将jQuery代码重新格式化为纯JavaScript,但在这个实例中实际上不能使用jQuery window
另外,我正在玩的中途完成的非功能性代码,以缓解掉票:
:-(
答案 0 :(得分:6)
此解决方案在跨度上运行,展开它们(必要时),然后继续使用刚刚解开的元素,以便处理所有这些元素。左边只是文本节点子节点的顶级跨度。
function wrap(text, color) {
var span = document.createElement("span");
span.style.color = color;
span.appendChild(text);
return span;
}
function format(p) {
for (var cur = p.firstChild; cur != null; cur = next) {
var next = cur.nextSibling;
if (cur.nodeType == 3) {
// top-level text nodes are wrapped in spans
next = p.insertBefore(wrap(cur, p.style.color), next);
} else {
if (cur.childNodes.length == 1 && cur.firstChild.nodeType == 3)
continue;
// top-level spans are unwrapped…
while (cur.firstChild) {
if (cur.firstChild.nodeType == 1)
// with nested spans becoming unnested
p.insertBefore(cur.firstChild, next);
else
// and child text nodes becoming wrapped again
p.insertBefore(wrap(cur.firstChild, cur.style.color), next);
}
// now empty span is removed
next = cur.nextSibling;
p.removeChild(cur);
}
}
p.style.color = p.firstChild.style.color;
}