【问题标题】:jQuery.replaceWith, changing <br /><br /> to </p>?jQuery.replaceWith,将 <br /><br /> 更改为 </p>?
【发布时间】:2011-12-05 02:30:08
【问题描述】:

我正在使用一个 CMS 来代替我喜欢的段落标签。 我试过了:

$('<br /><br />').replaceWith('</p>');

现在在你笑完之后;请让我知道这是否可行,如果可行,最好的解决方法。

更新(来自 OP 评论):
段落不是空的,它们在开头有一个&lt;p&gt; 标签,最后一个段落以&lt;/p&gt; 结束,中间的段落用双&lt;br&gt; 标签隔开。

我无法访问编辑器代码,这是我的问题。这是定制的,很糟糕。

【问题讨论】:

  • 这是一个空的&lt;p&gt;&lt;/p&gt;?如果是这样,意义何在?
  • 这是服务端的工作,不是 jQuery/前端
  • 您可以访问编辑器代码吗?大多数所见即所得的编辑器都有一个设置来改变它。
  • 段落不是空的,它们在开头有一个 p 标签,最后一个段落以 /p 结尾,中间的段落用双 br 标签隔开。我无法访问编辑器代码,这是我的问题,它是自定义构建并且很糟糕。
  • 从什么时候开始操作 DOM 成为服务器的工作?您的服务器 html 知道吗?听起来您可能需要将逻辑和表示分开一点。

标签: jquery html paragraphs


【解决方案1】:

您可以尝试以下几种方法。更可取的一个(因为您已经在使用 jQuery)可能是使用 contents():

$('.your_cms_container').contents().filter(function() {
    return this.nodeType == 3;  // Only text nodes
}).wrap('<p></p>')

这会将所有文本节点包裹在段落标签中。通过撕掉所有的
标签来遵循这一点:

$('.your_cms_container').filter('br').remove();

当然,如果您的文本节点不都是主文本容器的所有简单子节点,情况会变得更加复杂。

另一个(肮脏的)选项只是手动修改 html,然后在完成后将其放回 jQuery:

var htmlAsString = $('.your_cms_container').html();    // Get the contents as simple text

... // Do nasty things to the string here

$('.your_cms_container').html(htmlAsString);    // Put it back and let jQuery try and sort out any mess

我并不是说第二种方法是错误的,有时它是在不重写所有内容的情况下完成工作的唯一方法。但是如果我不得不这样做,它仍然会让我感到肮脏;-)

【讨论】:

    【解决方案2】:
    1. 获取所有&lt;br&gt; 节点。或者,直接忽略那些 在&lt;p&gt; 块内。
    2. 然后,对于每个 &lt;br&gt; 节点,包装紧接在它之前或紧随其后的所有文本节点。
    3. 最后,删除&lt;br&gt; 节点。

    这种方法处理嵌套,不会丢弃链接、页面布局等。

    代码:

    $('.your_cms_container br').each ( function () {
        if (this.parentNode.nodeName != "P") {
            $.each ([this.previousSibling, this.nextSibling], function () {
                if (this.nodeType === 3) { // 3 == text
                    $(this).wrap ('<p></p>');
                }
            } );
    
            $(this).remove (); //-- Kill the <br>
        }
    } );
    


    更新:

    编辑 OP 的问题后,我意识到我没有完全解决他的具体情况。 (我使用上面的代码,在用户脚本中效果很好。)

    他想改变这一点:

    <p> "Paragraph 1" <br />
        <a href="http://xkcd.com/246/">Link, the first</a>
        Line after single break.
        <br /><br />
        "Paragraph 2"
    </p>
    

    进入这个:

    <p> "Paragraph 1" <br />
        <a href="http://xkcd.com/246/">Link, the first</a>
        Line after single break.
    </p>
    <p> "Paragraph 2" </p>
    


    困难在于:您不想丢弃嵌套元素(如果有)或事件处理程序(如果有)。

    为此,请使用以下方法:

    1. 使用p:has(br+br) 之类的选择器仅抓取有问题的段落。请注意,相邻的选择器会忽略文本节点——在这种情况下,我们不希望它这样做。
    2. 逐一遍历每个违规段落的内容。
    3. 使用状态机在每个&lt;br&gt;&lt;br&gt; 创建一个新段落并将内容节点移动到适当的&lt;p&gt;。

    代码如下所示。你可以see it in action at jsFiddle:

    var badGraphs   = $("#content p:has(br+br)");
    var targetP     = null;
    var justSplit   = false;
    
    badGraphs.each ( function () {
        var parentP = $(this);
    
        parentP.contents ().each ( function (J) {
            if (justSplit) {
                justSplit = false;
                // Continue the loop. Otherwise, it would copy an unwanted <br>.
                return true;    
            }
            var thisjNode   = $(this);
            var nextjNode   = $(this.nextSibling);
    
            if (thisjNode.is ("br")  &&  nextjNode.is ("br") ) {
                thisjNode.remove (); //-- Kill this <br>
                nextjNode.remove (); //-- and the next
    
                //-- Create a new p for any following content
                targetP     = targetP || parentP;
                targetP.after ('<p></p>');
                targetP     = targetP.next ("p");
    
                justSplit   = true;
            }
            else if (targetP) {
                //-- Move the node to its new home.
                targetP.append (this);
            }
        } );
    } );
    

    【讨论】:

      【解决方案3】:

      如果你的服务器语言是php,那么你可以使用str_replace()

      http://php.net/manual/en/function.str-replace.php

      【讨论】:

      • 谢谢阿米拉,我会调查的
      【解决方案4】:

      这是您问题的答案:

      $( 'br' ).before( '<p></p>' ).remove();
      

      但如前所述,最好在服务器端做类似的事情

      【讨论】:

      • 在服务器上操作表示层并不好。
      • 这实际上只是在 &lt;br&gt; 元素曾经所在的位置放置了一大堆空的 &lt;p&gt;&lt;/p&gt; 节点。
      猜你喜欢
      • 1970-01-01
      • 2014-01-24
      • 2013-07-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-14
      • 1970-01-01
      相关资源
      最近更新 更多