Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/397.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用JavaScript调整DOM中的嵌套跨距以优化HTML编辑器输出_Javascript_Html_Dom - Fatal编程技术网

使用JavaScript调整DOM中的嵌套跨距以优化HTML编辑器输出

使用JavaScript调整DOM中的嵌套跨距以优化HTML编辑器输出,javascript,html,dom,Javascript,Html,Dom,我需要使用JavaScript重新格式化输入HTML,以便生成的输出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

我需要使用JavaScript重新格式化输入HTML,以便生成的输出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>

此解决方案将在跨度上运行,将其展开(如有必要),然后继续处理刚刚展开的图元,以便处理所有这些图元。左侧仅为具有文本节点子级的顶级跨距

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

()

我首先选择所有的
span
s,然后检查它们的父项是什么。如果它也是
span
,请检查父级的innerHTML和子级的outerHTML。如果相等,则为嵌套冗余跨距。然后使用子级的innerHTML替换父级的innerHTML。不会为你做的,因为你自己没有尝试过任何东西,也没有发布过。:)如果p中没有span,那么只需将其添加到其中,这应该是更简单的部分;)哦,对不起,现在我看到我误读了这个问题,对不起:DOk,我几乎在那里(或者我以为我在那里),在JSFIDLE上编辑它,然后我做了一个无限循环,不得不强制关闭面板并失去了进度,我放弃了,即使使用JSFIDLE,我也应该做更多的备份:'(Ug,感谢您尝试@Jakub!我仍然有您的旧版本代码,并正在使用它重新格式化我的代码。它对某些情况有效,但对其他情况无效,但我认为我进展缓慢。非常感谢!我不得不使用
cur.childNodes.length
而不是
cur.children.length
,这可能是一件微不足道的事情。您应该得到一个悬赏!哦,对了。
.children
是HTML元素集合,不包括
.childrendes
所需的文本节点。
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;
}