- 获取所有
<br> 节点。或者,直接忽略那些
在<p> 块内。
- 然后,对于每个
<br> 节点,包装紧接在它之前或紧随其后的所有文本节点。
- 最后,删除
<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>
困难在于:您不想丢弃嵌套元素(如果有)或事件处理程序(如果有)。
为此,请使用以下方法:
- 使用
p:has(br+br) 之类的选择器仅抓取有问题的段落。请注意,相邻的选择器会忽略文本节点——在这种情况下,我们不希望它这样做。
- 逐一遍历每个违规段落的内容。
- 使用状态机在每个
<br><br> 创建一个新段落并将内容节点移动到适当的<p>。
代码如下所示。你可以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);
}
} );
} );