使用SPAN标记在HTML文本中包围单个单词?

时间:2011-02-20 20:06:42

标签: javascript html regex

我需要使用SPAN标记在HTML元素中包围单个单词。所以像这样:

Foo <span class="f1 b0">bar <b>baz</b> boo blah</span> lorem ipsum

应该成为这个:

<span>Foo</span> <span class="f1 b0"><span>bar</span> <b><span>baz</span></b>
<span>blah</span></span> <span>lorem</span> <span>ipsum</span>

原因是我希望能够找出哪个词,特别是在光标下使用“document.elementFromPoint(X,Y)”。我尝试使用一个简单的正则表达式:

theElement.innerHTML.replace(/\b(\w+)\b/g, "<span>$1</span>")

...但是这不起作用,因为有问题的HTML元素肯定会在其中包含元素。我只是在innerText而不是innerHTML上使用该正则表达式,但后来我将丢失所有现有的格式。

我试过走元素的子元素,在每个子元素上执行正则表达式替换,但有时子元素在其中有自己的HTML标记,我无法弄清楚如何替换之前或之后的文本标签

任何人都有一个很好的解决方案吗?

3 个答案:

答案 0 :(得分:4)

为此,您需要遍历DOM并了解如何处理各个节点。

基本行走代码是:

function walk(root)
{
    if (root.nodeType == 3) // text node
    {
        doReplace(root);
        return;
    }
    var children = root.childNodes;
    for (var i = children.length - 1 ; i >= 0 ; i--)
    {
        walk(children[i]);
    }
}

walk函数检查输入节点的所有子节点,并且:

  • 如果它看到一个文本节点,则会调用替换函数
  • 否则它以子节点作为新的输入节点递归调用自身。

请注意,因为代码就地替换了节点,所以“children”节点列表将受到替换的影响。为避免这种情况影响算法,将以相反的顺序访问子节点。

doReplace函数是这样的:

function doReplace(text)
{
    var div = document.createElement("div");
    div.innerHTML = text.nodeValue.replace(/\b(\w+)\b/g, "<span>$1</span>");
    var parent = text.parentNode;
    var children = div.childNodes;
    for (var i = children.length - 1 ; i >= 0 ; i--)
    {
        parent.insertBefore(children[i], text.nextSibling);
    }
    parent.removeChild(text);
}

这将创建一个容器节点,然后应用正则表达式并使用innerHTML将结果解析为DOM片段。然后,div元素的子元素可以替换文档中的文本节点。同样,节点的移动以相反的顺序完成,因此源节点列表的变化不会影响循环。

最后,可以通过调用walk函数来应用更改。

e.g。

window.onload = function() { walk(document.body); };

可在http://www.alohci.net/text/html/wordwrapper.htm.ashx

找到完整的工作示例

答案 1 :(得分:0)

您可以检查source this jQuery plugin以查看他们是如何做到的,然后提取您需要的功能。

答案 2 :(得分:0)

尝试使用.wrap() jQuery方法