使用Javascript创建删除某些不需要的元素的节点树

时间:2015-01-02 23:50:55

标签: javascript dom tree nodes

我正在使用WYSIWYG编辑器,并尝试清理我从中获得的内容。以下是两个转换示例

<div>                       <div>
  <p>                         <blockquote>
    <blockquote>                <span>
      <p>                         <b>
        <span>      --->            <i>
          <b>       --->              <u>
            <u>               <p>
              <i>               Text
    <p>                       <p>
      Text                      Text
    Text

OR

<div>                       <div>
  <p>                         <blockquote>
    <blockquote>                <h1>
      <h1>                        Text
        Text                      <ul>
        <ul>                    Text
      Text          --->      <p>
    Text            --->        Text
    <h3>                      <h3>
  <p>                         <p>
    Text                        Text
    <b>                         <b>
      <i>                         <i>
  <h2>                        <h2>

那么,这里发生了什么:

<p><blockquote><h*>不允许在彼此之内。 仅<p>的直接后代允许<blockquote><h*><ul><ol><div>。其他任何东西都应该在其中一个内部。

所以我需要做的是有效地走树,并将它们放在正确的层次结构中。

从第一个示例中可以看出,<blockquote><p>拉出,<p><p>拉出,然后,创建新的<p>以保留剩余的Text,并删除第一个<p>(至少我是这样看的,它也可能是最后一个Text在未使用的<p>)内。

第二个,<blockquote>被移出<p>,剩余的Text被放置在新的<p>或未使用的<p>中,无论你看到了什么,<h3><p>所取代,其他一切都很好,所以它就不管用了。

我真的无法将逻辑正确地放到正确放置元素的位置,并创建新元素。请记住,这是一个非常浅薄的示例,但我可能需要说出几个级别的东西,或删除一个没有做任何事情的节点,(<p>内部<blockquote>)。

这是我提出的最好的伪,但它仍有问题。

if not p and not BQ and not h*
    create p
    fragment.appendChild(node)
else if (p && hasParent(p || BQ || H*)) or 
        (h* && hasParent(p || h*)) or
        (BQ && hasParent(p || h*)
            fragment.appendChild(node)
else
    fragment.lastChild.appendChild(node)

它不起作用,因为第一个if会不断在子节点上创建<p>,就像Text内的<blockquote>一样。还有一些其他错误,但重要的是它是有缺陷的逻辑。

有人能帮助我理解这个逻辑吗?伪代码显然很好,但我真的很难绕过这个层次结构。在我看来,递归函数可能是有用的,但我还没有想到一些中等的东西。

感谢所有帮助,谢谢。

1 个答案:

答案 0 :(得分:0)

这是我最终的结果。基本上,如果我找到一个不符合标准的节点,那么会发生什么,以及它之后的所有内容都会移到父级之下。只需重复此过程,直到一切都有效。

isValidTree的代码未显示。所有这一切都是根据我正在寻找的规则来验证子树。如果树无效,则返回node,告诉我从哪里开始删除,或者在该树内部的一切都没问题。

function rebuildTree(doc, node){
    // Keep track the original tree
    var original = node.parentNode;

    // As long as node is valid
    while(node){
        // Remember who the next sibling is, that way we can keep inserting before it
        var sibling = node.nextSibling;

        // Check if node is valid
        var badNode = isValidTree(node);

        // If we didn't get true back, then we need to move badNode, and all next-siblings to after the parent
        if(badNode !== true){
            // Get the next sibling, so we don't lose track of it
            var nextNode = badNode.nextSibling;

            // While we have a badNode
            while(badNode){
                // If we have a text node
                if(badNode.nodeName.toLowerCase() === "#text"){
                    // Create a paragraph
                    var p = doc.createElement("p");
                    // And place the textNode into the paragraph
                    p.appendChild(badNode);

                    // Then insert the node before the sibling
                    node.parentNode.insertBefore(p, sibling);

                    // And remove the original
                    badNode.parentNode.removeChild(badNode);
                }
                // Otherwise, we can just insert the badNode before the sibling
                else{
                    node.parentNode.insertBefore(badNode, sibling);
                }

                // Then assign badNode to be the nextNode
                badNode = nextNode;
                // And get the nextNode (If it's not null yet)
                if(nextNode){
                    nextNode = badNode.nextSibling;
                }
            }
        }
        // Now go to the next sibling of node, which at this point may be one of it's once-was children
        node = node.nextSibling;
    }
    // Return the node's parent (i.e. the entire tree)
    return original;
}