【问题标题】:Recreating a node tree removing certain, uneeded elements with Javascript使用 Javascript 创建删除某些不需要的元素的节点树
【发布时间】:2015-03-01 06:12:31
【问题描述】:

我正在使用所见即所得的编辑器,并试图清理我从中得到的回报。这里有两个转换的例子

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

或

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

那么,这里发生了什么:

&lt;p&gt;、&lt;blockquote&gt; 和 &lt;h*&gt; 不允许在彼此内部。 &lt;p&gt;、&lt;blockquote&gt;、&lt;h*&gt;、&lt;ul&gt; 和 &lt;ol&gt; 只能是 &lt;div&gt; 的直系后代。其他任何东西都应该在其中之一内。

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

从第一个示例中可以看出,&lt;blockquote&gt; 被拉出&lt;p&gt;,&lt;p&gt; 被拉出&lt;p&gt;,然后,创建了一个新的&lt;p&gt; 来保存剩下的Text,第一个&lt;p&gt;被删除(至少我是这么看的,它也可能是最后一个Text被放入未使用的&lt;p&gt;中)。

第二个,&lt;blockquote&gt; 被拉出&lt;p&gt;,剩下的Text 被放入一个新的&lt;p&gt;,或者未使用的&lt;p&gt;,不管你怎么看,&lt;h3&gt;被拉出&lt;p&gt;,其他一切都很好,所以不管它。

我真的很难将逻辑正确地放在正确放置元素并创建新元素的位置。请记住,这是一个非常肤浅的例子,但我可能需要说将一些东西拉出几层,或者删除一个没有做任何事情的节点(&lt;p&gt; 在&lt;blockquote&gt; 内)。

这是我想出的最好的伪代码,但它仍然存在问题。

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 会不断在子节点上创建 &lt;p&gt;,就像 &lt;blockquote&gt; 内部的 Text。还有一些其他错误,但重要的是它的逻辑有缺陷。

谁能帮我把这个逻辑弄对吗?伪代码显然很好,但我真的很难理解这个层次结构。我突然想到递归函数可能有用,但我什至没有想出半点不错的东西。

感谢所有帮助,谢谢。

【问题讨论】:

    标签: javascript dom tree nodes


    【解决方案1】:

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

    isValidTree 的代码未显示。所做的只是根据我正在寻找的规则验证子树。如果树无效,它会返回 node,告诉我从哪里开始删除,或者如果树内一切正常,则返回 true。

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

    【讨论】:

      猜你喜欢
      • 2015-10-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-08
      • 1970-01-01
      • 2021-07-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多