gpt4 book ai didi

javascript - 使用 JavaScript 展平 DOM 中的嵌套跨度以优化 HTML 编辑器输出

转载 作者:数据小太阳 更新时间:2023-10-29 06:11:59 24 4
gpt4 key购买 nike

我需要使用 JavaScript 重新格式化输入 HTML,以便生成的输出 HTML 始终是 <p> 的序列包含一个或多个<span>的节点节点和每个 <span>节点应该包含恰好一个 #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>

HTML 看起来像这样:

<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 编辑器中。 HTML 需要符合此模式以使应用程序更有用并提供具有可用 HTML 的 PDF 输出引擎(wkhtmltopdf 如果 HTMl 变得过于复杂且嵌套跨度导致在 TinyMCE 中编辑不直观,则会出现行高问题)
  • jQuery 不可用。 Prototype.JS 在父级中可用 window但不直接在本文档中。我自己能够将 jQuery 代码重新格式化为纯 JavaScript,但实际上无法在此实例中使用 jQuery :-(
  • 是的,我有现成的代码。这个逻辑显然错得离谱,现在不值得分享。我现在正在努力改进它,如果我能把它变得相当接近,我会分享它,这样它就会很有用
  • 我真的知道我在做什么!我只是盯着这段代码看得太久了,所以我现在不知道要使用的正确算法......

我还在玩的额外的、半途而废的非功能性代码,以减少反对票:

function reformatChildNodes(node) {
var n,l,parent;
if(node.nodeName.toLowerCase() == 'p') {
// We are on a root <p> node, make that it has at least one child span node:
if(!node.childNodes.length) {
var newSpan = document.createElement('span');
/* set style on newSpan here */
node.appendChild(newSpan);
}
if(node.childNodes[0].nodeName.toLowerCase() != 'span') {
// First child of the <p> node is not a span, so wrap it in one:
var newSpan = document.createElement('span');
/* set style on newSpan here */
newSpan.appendChild(node.childNodes[0]);
node.appendChild(newSpan);
}
// Now repeat for each child node of the <p> and make sure they are all <span> nodes:
for(n=0;n<node.childNodes.length;++n)
reformatChildNodes(node.childNodes[n]);
} else if(node.nodeName.toLowerCase() == 'span') {
// We are on a <span> node, make that it has only a single #text node
if(!node.childNodes.length) {
// This span has no children! it should be removed...
} else if(node.parentNode.nodeName.toLowerCase() != 'p') {
// We have a <span> that's not a direct child of a <p>, so we need to reformat it:
node.parentNode.parentNode.insertBefore(node, parent);
} else {
for(n=0;n<node.childNodes.length;++n)
reformatChildNodes(node.childNodes[n]);
}
} else if(node.nodeName.toLowerCase() == 'div') {
// This is justa dirty hack for this example, my app calls reformatChildNodes on all nodes
for(n=0;n<node.childNodes.length;++n)
reformatChildNodes(node.childNodes[n]);
}
}

最佳答案

此解决方案遍历跨度,展开它们(在必要时),然后继续处理刚刚展开的元素,以便它处理所有这些元素。左边只有带有文本节点子节点的顶级跨度。

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;
}

( Demo at jsfiddle.net )

关于javascript - 使用 JavaScript 展平 DOM 中的嵌套跨度以优化 HTML 编辑器输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18904675/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com