Javascript 在不分离的情况下包装文本节点(<;br>;?

Javascript 在不分离的情况下包装文本节点(<;br>;?,javascript,jquery,Javascript,Jquery,是否有一种方法可以在包含作为节点一部分的同时包装文本节点,而不是在每个处拆分节点?我希望节点仍然在块元素上拆分,如 如果我有一个元素 <div id=test>This is <br> a sentence.<p>This is <br> another.</p></div> 这是一个句子。这是另一个句子 我打电话 $('#test').contents().filter(function () { return (th

是否有一种方法可以在包含

作为节点一部分的同时包装文本节点,而不是在每个

处拆分节点?我希望节点仍然在块元素上拆分,如

如果我有一个元素

<div id=test>This is <br> a sentence.<p>This is <br> another.</p></div>
这是一个句子。这是另一个句子

我打电话

$('#test').contents().filter(function () {
return (this.nodeType == 3)
}).wrap('<span>');
$('#test').contents().filter(函数(){
return(this.nodeType==3)
}).wrap(“”);
这导致

<div id=test><span>This is</span> <br><span> a sentence.</span><p><span>This is</span><br><span> another</span></p></div>
这是一个句子。这是另一个句子

我期望的结果是

<div id=test><span>This is <br> a sentence.</span><p>This is <br> another.</p></div>
这是一个句子。这是另一个句子

我怎样才能做到这一点呢?

试试看

$(“#测试”).html(函数(i,html){
var p=$.parseHTML(html).filter(函数(el,i){
返回el.tagName==“P”
});
返回$(“”){
“html”:$(this.contents().filter(函数(idx,el)){
返回el.nodeType==3
||el.tagName==“BR”
||el.tagName!=“P”
})
}).add(p)
});
log($(“#测试”)[0].outerHTML)


这是一个句子。这是另一个。

这是一种暴力方式。它遍历
#test
的每个直接子级,并收集textNodes+br标记的序列,当序列结束时,它将在一个范围内包装到目前为止积累的内容

function wrapPlainTextWithBR(selector) {
    var cum = [];
    function flush(pos) {
        if (cum.length) {
            var temp = document.createElement("span");
            $(pos).before(temp);
            var span = $("<span>").append(cum);
            $(temp).after(span);
            $(temp).remove();
            cum.length = 0;
        }
    }

    var items = $(selector).contents();
    items.each(function(index, element) {
        if (this.nodeType === 3 || (this.nodeType === 1 && this.tagName === "BR")) {
            cum.push(this);
            // if we just processed the last element, then flush now
            if (index === (items.length - 1)) {
                flush(this);
            }
        } else {
            // found non-text node, non-BR, flush any in the cum list
            flush(this);
        }
    });
}

wrapPlainTextWithBR("#test");

工作演示:

您试图解决的实际终端问题是什么?我只想防止大量冗余的html标记。我有一个WYSIWYG编辑器,它使用这种方法添加标记。当我使用简单的html dom和htmlPurifier对html进行验证时,内容中的标记越多,验证所需的时间就越长。但是为什么要首先添加span标记?我并不是只添加span标记。我添加了em、strong、u、strike和span标签的组合。为了简单起见,我在示例中使用了span。@user3591017问题更新将问题从“包装文本节点而不在
上分离”更改为?在“我想要的结果是:
这是一个句子。这是另一个。

。用
包装
innerHTML
的逻辑是什么?我尝试了新示例,它删除了p。有没有一种方法可以在保留段落的同时做到这一点?@user3591017——如果你说的“资源扩展”是指它是否使用了大量内存——我不这么认为,因为它只是在移动DOM元素。由于所有的DOM操作,它将触发回流。@user3591017-我添加了一个稍微简化的版本,它利用了jQuery的
.wrapAll()
function wrapPlainTextWithBR(selector) {
    var cum = [];
    function flush(pos) {
        if (cum.length) {
            $(cum).wrapAll("<span />");
            cum.length = 0;
        }
    }

    var items = $(selector).contents();
    items.each(function(index, element) {
        if (this.nodeType === 3 || (this.nodeType === 1 && this.tagName === "BR")) {
            cum.push(this);
            // if we just processed the last element, then flush now
            if (index === (items.length - 1)) {
                flush(this);
            }
        } else {
            // found non-text node, non-BR, flush any in the cum list
            flush(this);
        }
    });
}