如何在标签中包装HTML子字符串?

时间:2018-02-17 16:49:57

标签: javascript html replace textwrapping

我需要使用Javascript将HTML字符串的一部分包装在新元素中。例如:

<div>This is some text.<b title="some text">This is some other element</b></div>

对此:

<div>This is <a>some text</a>.<b title="some text">This is some other element</b></div>

这是我目前的代码,简化:

var s = "some text"
var regExp = RegExp(s, 'i');
element.innerHTML = element.innerHTML.replace(regExp, '<a>$&</a>');
<div>This is some text.<b title="some text">This is some other element</b></div>

此代码适用于普通情况,但是当存在与我的搜索过滤器匹配的标记的子元素时失败,如上面的title属性中所示。此外,它似乎打破了元素引用,因为在设置innerHTML时元素被重新初始化(并且内部HTML似乎非常不鼓励)。

我认为通过查找textNode,解析它,并在其位置创建新节点,这应该是可行的,但我很难让它工作。

3 个答案:

答案 0 :(得分:0)

HTML不是常规语言,因此无法通过正则表达式(完全)解析。请参阅此文章:RegEx match open tags except XHTML self-contained tags

答案 1 :(得分:0)

如果您将文本包装在一个范围内,则可以使用以下代码:

<div id="id1"><span>This is some text.</span><b title="some text">This is some other element</b><span class="some text">some text</span></div>

<script type="text/javascript">
    var id = document.getElementById("id1");

    var all = id.querySelectorAll("*");
    var length = all.length;
    for (var i = 0; i < length; i++) {
        all[i].innerHTML = all[i].innerHTML.replace('some text', '<a>some text</a>');      
    }

</script>

答案 2 :(得分:0)

经过一些修修补补后,我终于开始工作了,只是直接修改了DOM。

// JQuery required for this line.
var textNodes = $.grep(element.childNodes, function(n) { return n.nodeType == Node.TEXT_NODE });

// Assume there is only one text node in element (I know this from my use case).
if (textNodes.length > 0) {
  var textNode = textNodes[0];
  var regExp = RegExp('^(.*)('+someText+')(.*)', 'i');
  var matches = textNode.nodeValue.match(regExp);
  textNode.nodeValue = matches[1];
  var matchNode = document.createElement('U');
  matchNode.appendChild(document.createTextNode(matches[2]));
  label.insertBefore(matchNode, textNode.nextSibling);
  suffixNode = document.createTextNode(matches[3]);
  label.insertBefore(suffixNode, matchNode.nextSibling);
}

引入一个新的span元素并设置innerHTML也会有效,但我更喜欢保持DOM尽可能干净。