我正在编写一个Chrome扩展程序,它会在与某个正则表达式匹配的每个字符串周围添加<span> ... </span>
。 RegEx匹配工作完美,但我似乎找不到在文本周围正确添加span
标记的方法。
到目前为止我的代码是:
// main.js
var regex_pattern = new RegEx('(apple)', 'g'); // Let's pretend I want to match every instance of 'apple'
var textNodes = getTextNodes(); // A function that returns a list of every text node from the DOM
for (var i = 0; i < textNodes.length; i++) {
if (textNodes[i].nodeValue.match(regex_pattern)) {
textNodes[i].nodeValue = textNodes[i].nodeValue.replace(regex_pattern, "<span class='highlight'>$&</span>");
}
}
这将正确识别我的RegEx模式的每个匹配项(在本例中为&#39; apple&#39;)和输出<span class="highlight">apple</span>
。唯一的问题是Chrome不会将其视为HTML,而是将其视为文本 - 因此不要看世界&#39; apple&#39;根据{{1}}类设置样式,可以看到文字输出:highlight
为什么会发生这种情况,如何修复它以便正确应用样式?意识到这不是理想的,我尝试使用<span class="highlight">apple<span>
方法将匹配的文本包装在一个范围内,但是这没有做任何事情,它会出错或者无法添加{{1} } node,取决于我如何调整代码。感谢您提供的任何见解!
答案 0 :(得分:1)
您不能使用nodeValue
替换任意HTML的文本节点。
您必须手动执行此操作:
function replaceNodeWithHTML(node, html) {
var parent = node.parentNode;
if(!parent) return;
var next = node.nextSibling;
var parser = document.createElement('div');
parser.innerHTML = html;
while(parser.firstChild)
parent.insertBefore(parser.firstChild, next);
parent.removeChild(node);
}
var regex_pattern = /(apple)/g;
var textNodes = [document.querySelector('div').firstChild];
for (var i = 0; i < textNodes.length; i++)
if (textNodes[i].nodeValue.match(regex_pattern))
replaceNodeWithHTML(
textNodes[i],
textNodes[i].nodeValue.replace(regex_pattern, "<span class='highlight'>$&</span>")
);
.highlight {
background: yellow;
}
<div>I have an (apple). You have an (apple) too.</div>
如果节点有insertAdjacentHTML
方法,但只有元素可以。
答案 1 :(得分:0)
在元素上设置.innerHTML。设置textNode.nodeValue值可直接设置文本。