包装textNodes而不分离?

时间:2015-03-17 23:07:30

标签: javascript jquery

有没有办法在包含<br>作为节点的一部分时包装文本节点,而不是在每个<br>拆分节点我希望节点仍然在块元素上分解,如{ {1}}。 ?

如果我有元素

<p>

我打电话给

<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>');

我想要的结果是

<div id=test><span>This is</span> <br><span> a sentence.</span><p><span>This is</span><br><span> another</span></p></div>

我怎样才能做到这一点?

2 个答案:

答案 0 :(得分:1)

尝试

&#13;
&#13;
$("#test").html(function(i, html) {
  var p = $.parseHTML(html).filter(function(el, i) {
      return el.tagName === "P" 
  });
  return $("<span />", {
           "html": $(this).contents().filter(function(idx, el) {
                     return el.nodeType === 3 
                            || el.tagName === "BR" 
                            || el.tagName !== "P"
                   })
         }).add(p)     
});

console.log($("#test")[0].outerHTML);
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>
<div id=test>This is <br> a sentence.<p>This is <br> another.</p></div>
&#13;
&#13;
&#13;

答案 1 :(得分:1)

这是一种蛮力的方式。它遍历#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");

工作演示:http://jsfiddle.net/jfriend00/zgcaeszn/


编辑:我意识到可以通过使用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);
        }
    });
}

工作演示:http://jsfiddle.net/jfriend00/wemwerjv/