替换元素中的内容而不替换HTML

时间:2017-05-05 16:05:09

标签: jquery html replace preserve

假设我有以下HTML结构:

<test>
    <div>
        This is a test
        </div>
    <div>
        This is another test
        <button>
            Button test
        </button>
    </div>
</test>

现在我使用以下jQuery代码替换,例如'T':

$("test *").each(function(index, value) {
    $(this).html($(this).html().replace(new RegExp('t', "ig"), "<b>t</b>"));
});

但是,这会产生以下HTML结构(这是意料之外的,请参阅<button>标记,这会破坏我的HTML):

<test>
    <div>
        <b>T</b>his is a <b>t</b>es<b>t</b>
        </div>
    <div>
        <b>T</b>his is ano<b>t</b>her <b>t</b>es<b>t</b>
        <bu<b>t</b><b>t</b>on>
            Bu<b>t</b><b>t</b>on <b>t</b>es<b>t</b>
            </bu<b>t</b><b>t</b>on>
        </div>
    </test>

我想要实现的目标是:

<test>
    <div>
        <b>T</b>his is a <b>t</b>es<b>t</b>
        </div>
    <div>
        <b>T</b>his is ano<b>t</b>her <b>t</b>es<b>t</b>
        <button>
            Bu<b>t</b><b>t</b>on <b>t</b>es<b>t</b>
            </button>
        </div>
    </test>

基本上,我想在整个元素中替换,但保留HTML标记和所有HTML属性。

2 个答案:

答案 0 :(得分:0)

看起来你想要加粗所有的T字符,但你的正则表达式也在捕捉你的HTML。

对innerText而不是innerHTML执行操作。我在几年内没有使用过jQuery,所以可能有一种更优化的方法,但这应该做到。

$("test *").each(function(index, value) {
    $(this)[0].innerText = $(this)[0].innerText.replace(new RegExp('t', "ig"), "<b>t</b>");
});

答案 1 :(得分:0)

你可以避免使用jQuery,而不是特别担心button(如果你点击input标签,这将无济于事等),如果你只在文本节点中替换。

我们寻找文本节点,在每种情况下都会发现我们看到的第一个“t”(或“T”),将其包裹在<b>中,然后继续前进。同一区域中的其他匹配将在后面的文本节点中找到。

var wrapText = "t";

var el = document.getElementsByTagName('test')[0];

replaceIn(el);

function replaceIn(el) {
  var i = 0;

  while (i < el.childNodes.length) {
    var cn = el.childNodes[i];

    if (cn.nodeType == 3) {   // text node
      var p = cn.textContent.toLowerCase().indexOf(wrapText);

      if (p >= 0) {
        var range = new Range();
        range.setStart(cn, p);
        range.setEnd(cn, p + 1);
        range.surroundContents(document.createElement('b'));
        ++i;   // don't check the <b> we just created
      }
    } 
    else {
      replaceIn(cn);
    }

    ++i;
  }
}
<test>
  <div>
    This is a test
  </div>
  <div>
    This is another test
    <button>
      Button test
   </button>

    <input value="input test" />
  </div>
</test>