【问题标题】:How to wrap HTML substring in tags?如何在标签中包装 HTML 子字符串?
【发布时间】:2018-07-28 08:35:11
【问题描述】:

我需要使用 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>');
&lt;div&gt;This is some text.&lt;b title="some text"&gt;This is some other element&lt;/b&gt;&lt;/div&gt;

此代码在普通情况下有效,但当有标记与我的搜索过滤器匹配的子元素时失败,如上面的标题属性。此外,它似乎破坏了元素引用,因为在设置 innerHTML 时元素被重新初始化(并且 innerHTML 似乎非常不鼓励)。

我认为这应该可以通过找到一个 textNode、解析它并在其位置创建新节点来实现,但我很难让它工作。

【问题讨论】:

  • 只需创建一个临时元素,并将字符串添加为 HTML。然后使用 DOM 解析器来提取/修改元素。

标签: javascript html replace word-wrap


【解决方案1】:

HTML 不是常规语言,因此它不能(完全)被正则表达式解析。请参阅此帖子:RegEx match open tags except XHTML self-contained tags

【讨论】:

    【解决方案2】:

    如果您将文本包装在一个跨度中,您可以使用以下代码:

    <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>
    

    【讨论】:

      【解决方案3】:

      经过一番修改,我终于让它工作了,只需要直接修改 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 尽可能干净。

      【讨论】:

        猜你喜欢
        • 2016-07-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-09-02
        • 1970-01-01
        • 2012-11-07
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多