一个简单的解决方案是简单地将innerHTML
元素的属性替换为一个新的 html 字符串,该字符串会将单词包装在span
. 但是,这不是一个非常灵活的解决方案,因为通过替换innerHTML
属性,所有元素都将被更新,这可能会产生意想不到的结果,除非您的目标元素只包含文本节点。
让我们假设body
包含此文本:
this is some text and I want to replace the word cool
你可以有:
var $body = $(document.body);
$body.html($body.html().replace(/\b(cool)\b/g, '<span style="color: red;">$1</span>'));
在这里,/\b(cool)\b/g
正则表达式将匹配每个很酷的单词并在它们上创建一个捕获组,允许我们在替换表达式中将其引用为$1
.
但是,最先进的解决方案可能会像这样实现:
我已经玩弄了这个概念,并为您创建了一个小提琴,展示了如何以任何您希望使用 aregex
来定位特定文本的方式操作文本。我创建了 2 个主要功能wrapText
,styleText
这将允许您对页面上的文本执行任何操作。它可以进一步优化,但你会明白的。
看看http://jsfiddle.net/scarsick/tX4Ge/1/
以下函数允许您将任何文本包装在文本节点中。
function wrapText(textNode, textRx, wrapFn) {
var global = textRx.global,
wrapEl,
result,
rightTextNode,
matchedText,
index;
while (result = textRx.exec(textNode.nodeValue)) {
rightTextNode = textNode.splitText(index = result.index);
rightTextNode.nodeValue = rightTextNode.nodeValue.substring((matchedText = result[0]).length);
wrapEl = wrapFn(matchedText, index);
wrapEl.appendChild(document.createTextNode(matchedText));
rightTextNode.parentNode.insertBefore(wrapEl, rightTextNode);
if (!global) {
break;
}
textNode = rightTextNode;
textRx.lastIndex = 0;
}
}
以下函数允许您设置元素中包含的任何文本的样式。
function styleText(el, textRx, styleFn) {
var wrapEl = document.createElement('span'),
slice = [].slice;
wrapEl.setAttribute('data-styled-text', 'true');
styleText = function(el, textRx, styleFn) {
var childNodes = slice.call(el.childNodes, 0),
i = 0,
len = childNodes.length,
node;
for (; i < len; i++) {
node = childNodes[i];
switch (node.nodeType) {
case 3:
if (!node.parentNode.getAttribute('data-styled-text')) {
wrapText(node, textRx, function (text, index) {
var el = wrapEl.cloneNode();
styleFn(el, text, index);
return el;
});
continue;
}
styleFn(node.parentNode);
break;
case 1:
styleText(node, textRx, styleFn);
break;
}
}
};
styleText(el, textRx, styleFn);
}