我认为处理这个问题的方法是遍历一个元素的所有后代,检查它是否是一个文本节点,并用一个跨度/类替换适当的内容。
var MyApp = {};
MyApp.highlighter = (function () {
"use strict";
var checkAndReplace, func,
id = {
container: "container",
tokens: "tokens",
all: "all",
token: "token",
className: "className",
sensitiveSearch: "sensitiveSearch"
};
checkAndReplace = function (node, tokenArr, classNameAll, sensitiveSearchAll) {
var nodeVal = node.nodeValue, parentNode = node.parentNode,
i, j, curToken, myToken, myClassName, mySensitiveSearch,
finalClassName, finalSensitiveSearch,
foundIndex, begin, matched, end,
textNode, span;
for (i = 0, j = tokenArr.length; i < j; i++) {
curToken = tokenArr[i];
myToken = curToken[id.token];
myClassName = curToken[id.className];
mySensitiveSearch = curToken[id.sensitiveSearch];
finalClassName = (classNameAll ? myClassName + " " + classNameAll : myClassName);
finalSensitiveSearch = (typeof sensitiveSearchAll !== "undefined" ? sensitiveSearchAll : mySensitiveSearch);
if (finalSensitiveSearch) {
foundIndex = nodeVal.indexOf(myToken);
} else {
foundIndex = nodeVal.toLowerCase().indexOf(myToken.toLowerCase());
}
if (foundIndex > -1) {
begin = nodeVal.substring(0, foundIndex);
matched = nodeVal.substr(foundIndex, myToken.length);
end = nodeVal.substring(foundIndex + myToken.length, nodeVal.length);
if (begin) {
textNode = document.createTextNode(begin);
parentNode.insertBefore(textNode, node);
}
span = document.createElement("span");
span.className += finalClassName;
span.appendChild(document.createTextNode(matched));
parentNode.insertBefore(span, node);
if (end) {
textNode = document.createTextNode(end);
parentNode.insertBefore(textNode, node);
}
parentNode.removeChild(node);
}
}
};
func = function (options) {
var iterator,
tokens = options[id.tokens],
allClassName = options[id.all][id.className],
allSensitiveSearch = options[id.all][id.sensitiveSearch];
iterator = function (p) {
var children = Array.prototype.slice.call(p.childNodes),
i, cur;
if (children.length) {
for (i = 0; i < children.length; i++) {
cur = children[i];
if (cur.nodeType === 3) {
checkAndReplace(cur, tokens, allClassName, allSensitiveSearch);
} else if (cur.nodeType === 1) {
iterator(cur);
}
}
}
};
iterator(options[id.container]);
};
return func;
})();
window.onload = function () {
var container = document.getElementById("container");
MyApp.highlighter({
container: container,
all: {
className: "highlighter"
},
tokens: [{
token: "sd",
className: "highlight-sd",
sensitiveSearch: false
}, {
token: "SA",
className: "highlight-SA",
sensitiveSearch: true
}]
});
};
演示:http: //jsfiddle.net/UWQ6r/1/
我对其进行了设置,以便您可以更改其中的值,id
以便您可以使用{}
传递给的不同键highlighter
。
对象中的两个设置all
指的是无论如何添加的类,以及区分大小写的搜索覆盖。对于每个标记,您指定标记、类以及匹配是否应区分大小写。
参考: