我需要使用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标记,我无法弄清楚如何替换之前或之后的文本标签
任何人都有一个很好的解决方案吗?
答案 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); };
找到完整的工作示例
答案 1 :(得分:0)
您可以检查source this jQuery plugin以查看他们是如何做到的,然后提取您需要的功能。
答案 2 :(得分:0)
尝试使用.wrap()
jQuery方法