6

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

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

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

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

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

4

4 回答 4

3

您可以尝试以下几种方法。更可取的一个(因为您已经在使用 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

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

于 2012-05-21T14:51:45.610 回答
2
  1. 获取所有<br>节点。或者,直接忽略<p>块内的那些。
  2. 然后,对于每个<br>节点,包装紧接在它之前或紧随其后的任何文本节点。
  3. 最后,删除<br>节点。

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

编码:

$('.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. 使用状态机在每个段落创建一个新段落<br><br>并将内容节点移动到适当的<p>.

代码看起来像这样。你可以在 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);
        }
    } );
} );
于 2013-10-07T00:51:54.977 回答
0

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

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

于 2011-10-11T08:40:21.553 回答
-5

这是您的问题的答案:

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

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

于 2011-10-11T08:46:55.537 回答